web-dev-qa-db-ja.com

doctrine2 dql、同様の比較を行う場合は、%ワイルドカードを含むsetParameterを使用します

パラメータプレースホルダーを使用したい-例?1-%ワイルドカード付き。つまり、「u.name LIKE%?1%」のようになります(ただし、これによりエラーがスローされます)。ドキュメントには次の2つの例があります:1。

// Example - $qb->expr()->like('u.firstname', $qb->expr()->literal('Gui%'))
public function like($x, $y); // Returns Expr\Comparison instance

コードインジェクションに対する保護がないため、これは好きではありません。

2。

// $qb instanceof QueryBuilder

// example8: QueryBuilder port of: "SELECT u FROM User u WHERE u.id = ?1 OR u.nickname LIKE ?2 ORDER BY u.surname DESC" using QueryBuilder helper methods
$qb->select(array('u')) // string 'u' is converted to array internally
   ->from('User', 'u')
   ->where($qb->expr()->orx(
       $qb->expr()->eq('u.id', '?1'),
       $qb->expr()->like('u.nickname', '?2')
   ))
   ->orderBy('u.surname', 'ASC'));

オブジェクトのプロパティ内で用語を検索する必要があるため、これは好きではありません。つまり、どちらかの側にワイルドカードが必要です。

29
waigani

パラメータをクエリにバインドするとき、DQLはPDO(Doctrine2が内部で使用するもの)とほとんど同じように機能します。

したがって、LIKEステートメントを使用する場合、PDOはキーワードと%ワイルドカードの両方を単一のトークンとして扱います。プレースホルダーの横にワイルドカードを追加することはできません。 paramsをバインドするときに、それらを文字列に追加する必要があります。

$qb->expr()->like('u.nickname', '?2')
$qb->getQuery()->setParameter(2, '%' . $value . '%');

PHPマニュアルのこの コメント を参照してください。お役に立てば幸いです。

72
Bryan M.

選択された答えはwrongです。動作しますが、セキュアではありません

パーセント記号の間に挿入する用語はエスケープする必要があります。

->setParameter(2, '%'.addcslashes($value, '%_').'%')

パーセント記号「%」と記号の下線「_」は、LIKEによってワイルドカードとして解釈されます。それらが適切にエスケープされていない場合、攻撃者はサービス拒否攻撃を引き起こす可能性がある任意に複雑なクエリを作成する可能性があります。また、攻撃者が想定外の検索結果を取得する可能性もあります。攻撃シナリオのより詳細な説明はここにあります: https://stackoverflow.com/a/7893670/623685

2
robert