I wrote a function that selects all the users from my database and all cooresponding fields using PDO. I also allowed the function to take an array as a parameter to allow for easy filtering. My problem is when I pass the filter array to the execute function I don't get any rows from my tables. I know it has something to do with PDO and the way I'm passing my array into it because when I run the execute method with the filter hard coded into the query it works. Here is my function and the code that is calling it:
$config = array(
'filters' => array(
'all members' => array('', ''),
'officers' => array('statuses.position_id', '8'),
'current members' => array('users.alumni', 0)
)
);
$filter = $config['filters'];
//Requested filter is just a constant used to keep track of the parsed $_GET value
$result = $dbh->getUsers($filter[REQUESTED_FILTER]);
//Just showed function, not whole class
public function getUsers(array $filter = array('', '')) {
$result = array();
$sql = 'SELECT users.firstname, users.lastname, users.grad_year, users.alumni, users.signedISA, phone_numbers.phone_number, emails.email_address,
addresses.name, addresses.street, addresses.city, addresses.state, addresses.zip
FROM
((users LEFT JOIN phone_numbers
ON users.user_id = phone_numbers.user_id)
LEFT JOIN emails
ON users.user_id = emails.user_id)
LEFT JOIN addresses
ON users.user_id = addresses.user_id
WHERE ? = ?;';
$sth = $this->handle->prepare($sql);
if($sth->execute($filter)) {
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
array_push($result, $row);
}
}
return $result;
}
Anyone have any idea why this isn't working?
You can't pass schema object identifiers (like table or column names) as parameters to a prepared statement (your current attempt is always comparing parameterised string literals from within the WHERE
clause).
Instead, you will need to do something like:
public function getUsers(array $filter = array('\'\'', '')) {
$result = array();
$sql = 'SELECT users.firstname, users.lastname, users.grad_year, users.alumni, users.signedISA, phone_numbers.phone_number, emails.email_address,
addresses.name, addresses.street, addresses.city, addresses.state, addresses.zip
FROM
((users LEFT JOIN phone_numbers
ON users.user_id = phone_numbers.user_id)
LEFT JOIN emails
ON users.user_id = emails.user_id)
LEFT JOIN addresses
ON users.user_id = addresses.user_id
WHERE ' . $filter[0] . ' = ?;';
$sth = $this->handle->prepare($sql);
if($sth->execute($filter[1])) {
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
array_push($result, $row);
}
}
return $result;
}
Beware of SQL injection if the value of $filter
is outside of your control (you'll need to quote identifiers with backticks and double-up any backticks contained therein: make sure you do this in a multi-byte safe way!).