5

パラメータ化されたクエリを実行して、ユーザーが指定したパラメータで検索を実行したいと思います。かなりの数のパラメーターがあり、それらのすべてが常に提供されるわけではありません。可能なすべてのパラメーターを指定する標準クエリを作成できますが、ユーザーが意味のあるパラメーター値を選択しなかった場合、これらのパラメーターの一部を無視するにはどうすればよいですか?

これが私が何をしようとしているのかを説明するための架空の例です

$sql = 'SELECT * FROM people WHERE first_name = :first_name AND last_name = :last_name AND age = :age AND sex = :sex';
$query = $db->prepare($sql);
$query->execute(array(':first_name' => 'John', ':age' => '27');

明らかに、提供されたパラメーターの数が期待されるパラメーターの数と一致しないため、これは機能しません。指定されたパラメーターのみがWHERE句に含まれるように毎回クエリを作成する必要がありますか、またはこれらのパラメーターの一部を無視するか、チェックすると常にtrueを返す方法はありますか?

4

4 に答える 4

8
SELECT * FROM people 
WHERE (first_name = :first_name or :first_name is null)
AND (last_name = :last_name or :last_name is null)
AND (age = :age or :age is null)
AND (sex = :sex or :sex is null)

パラメータを渡すときnullは、不要なものを用意してください。

この方法でクエリを実行できるようにするにはemulation mode、PDOを有効にする必要があることに注意してくださいON

于 2012-06-27T17:12:21.853 に答える
2

まず、$sql文字列を次のように変更することから始めます。

$sql = 'SELECT * FROM people WHERE 1 = 1';

これWHERE 1 = 1により、追加のパラメータを含めることができなくなります...

次に、$sql意味のある値を持つ追加のパラメーターを文字列に選択的に連結します。

$sql .= ' AND first_name = :first_name'
$sql .= ' AND age = :age'

文字$sql列には、提供する予定のパラメーターのみが含まれるようになったため、以前と同じように続行できます。

$query = $db->prepare($sql);
$query->execute(array(':first_name' => 'John', ':age' => '27');
于 2012-06-27T17:17:11.647 に答える
1

クエリを変更しても問題を解決できない場合...クエリの組み立てに役立つライブラリがいくつかあります。私はZend_Db_Select過去に使用したことがありますが、すべてのフレームワークに似たようなものがある可能性があります。

$select = new Zend_Db_Select;

$select->from('people');

if (!empty($lastName)) {
  $select->where('lastname = ?', $lastname);
}

$select->order('lastname desc')->limit(10);

echo $select; // SELECT * FROM people WHERE lastname = '...' ORDER BY lastname desc LIMIT 10
于 2012-06-27T17:14:09.807 に答える
0

@juergenによって与えられたソリューションをテストしましたが、バインドされた変数の数が一致しないため、PDOExceptionが発生します。次の(それほどエレガントではない)コードは、パラメーターの数に関係なく機能します。

function searchPeople( $inputArr )
{
  $allowed = array(':first_name'=>'first_name', ':last_name'=>'last_name', ':age'=>'age', ':sex'=>'sex');

  $sql  = 'SELECT * FROM sf_guard_user WHERE 1 = 1';

  foreach($allowed AS $key => $val)
  {
      if( array_key_exists( $key, $inputArr ) ){
          $sql .= ' AND '. $val .' = '. $key;
      }
  }

  $query = $db->prepare( $sql );
  $query->execute( $inputArr );
  return $query->fetchAll();
}

使用法:

$result = searchPeople(array(':first_name' => 'John', ':age' => '27'));
于 2012-06-27T18:21:00.880 に答える