简体   繁体   English

PDO执行不会正确注入数组值

[英]PDO execute won't inject array values properly

I wrote a function that selects all the users from my database and all cooresponding fields using PDO. 我编写了一个函数,该函数使用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. 我的问题是,当我将过滤器数组传递给execute函数时,我没有从表中得到任何行。 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. 我知道它与PDO和将数组传递给PDO的方式有关,因为当我使用将硬过滤器编码到查询中的方法运行execute方法时,它就可以工作。 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). 您不能将模式对象标识符(如表或列名)作为参数传递给已准备好的语句(您的当前尝试始终是比较WHERE子句中的参数化字符串文字)。

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!). 如果$filter的值不在您的控制范围之内,请当心SQL注入(您需要用反引号引起标识符并将所有反引号加倍:请确保以多字节安全方式进行此操作!)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM