1

PDOを使用して、データベースと対応するすべてのフィールドからすべてのユーザーを選択する関数を作成しました。また、簡単にフィルタリングできるように、関数が配列をパラメーターとして受け取ることを許可しました。私の問題は、フィルター配列を実行関数に渡すと、テーブルから行が取得されないことです。クエリにハードコードされたフィルターを使用してexecuteメソッドを実行すると、PDOと配列を渡す方法に関係があることはわかっています。これが私の関数とそれを呼び出しているコードです:

$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;
}

なぜこれが機能しないのか誰かが知っていますか?

4

1 に答える 1

1

スキーマオブジェクト識別子(テーブル名や列名など)をパラメーターとしてプリペアドステートメントに渡すことはできません(現在の試みでは、パラメーター化された文字列リテラルを常にWHERE句内から比較しています)。

代わりに、次のようなことを行う必要があります。

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;
}

の値が制御できない場合は、SQLインジェクションに注意し$filterてください(バッククォートを使用して識別子を引用し、そこに含まれるバッククォートを2倍にする必要があります。これはマルチバイトの安全な方法で行うようにしてください!)。

于 2012-09-15T01:48:06.747 に答える