LIKEステートメントでPDOパラメータ化クエリを作成するにはどうすればよいですか?


107

これが私の試みです:

$query = $database->prepare('SELECT * FROM table WHERE column LIKE "?%"');

$query->execute(array('value'));

while ($results = $query->fetch()) 
{
    echo $results['column'];
}

回答:


124

私が投稿した直後にそれを理解しました:

$query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
$query->execute(array('value%'));

while ($results = $query->fetch())
{
    echo $results['column'];
}

1
@Andrew:複数likeが使用されている場合はどうなりますか?実行配列はどのように順番に実行する必要がありますか?
ローガン2014

ありがとう。csharp + Mysql + ODBCで同様の問題があり、「select * from table where column like '%?%';」を使用して行を返さないようになりました。しかし、私が好きなら、「select * from table where column like?;」を実行したでしょうか。そして、パラメータ文字列を次のように設定します:string frag = $ "%{searchFragment}%"; 次に、パラメーター値にfragを使用します。奇妙な
sdjuan 2016年

2
PDOは実行呼び出しでその%をエスケープする必要があります。カカイの答えはより良い
Peter Bagnall

PDOStatement :: bindParamドキュメンテーションページでユーザーが投稿した一番上のメモは別のアプローチを提供していることに注意してください。バインドする前に変数にパーセント記号を追加します。
Dan Robinson

このスレッドの下部にある、Your Common Senseのページから取得したgavinのソリューションを見てください。シンプル。論理的。
RationalRabbit

85

名前付きパラメーターを使用する場合、MySQLデータベースの部分一致で使用LIKEする方法は次のとおりです。%

WHERE column_name LIKE CONCAT( '%'、:dangerousstring、 '%')

名前付きパラメータは :dangerousstringです。

言い換えると、%独自のクエリでは、エスケープされていない明示的な記号を使用します。これらの記号は、ユーザー入力ではなく、分離されています。

編集:Oracleデータベースの連結構文では連結演算子:を使用する||ため、次のようになります。

WHERE column_name LIKE '%' || :dangerousstring || '%'

ただし、@ bobinceがここで言及しているように、注意事項があります。

難易度は リテラル許可したいとき来る%_、それはワイルドカードとして機能しなくても、検索文字列内の文字を。

したがって、likeとパラメーター化を組み合わせるときに注意する必要があるのは、他にもあります。


6
+1-プレースホルダーが置き換えられた後、すべての連結がデータベースで行われるため、これは私にとって良いアプローチのように思われます。これは、名前付きプレースホルダーを使用できることを意味します。上記の構文はOracle用であり、MySQLでは構文は次のとおりですLIKE CONCAT('%', :something, '%')。参照:stackoverflow.com/a/661207/201648
アーロンニュートン

1
これは私には正確に機能しませんでしたが、正しい軌道に乗ることができました。LIKE '%':something '%'を実行する必要がありました。
Christopher Smit 2017年

私はこれが主題外であることを知っていますが、この文を使用してもSQLインジェクションを実行できました、なぜですか?
チアゴディアス

これは私にとってはうまくいきませんでした。SQLコマンドでテストしたところ、SELECT * FROM calculation WHERE ( email LIKE '%' || luza || '%' OR siteLocation LIKE '%'|| luza ||'%' OR company LIKE '%' ||luza ||'%' )エラーが発生しました。
Luzan Baral

@AaronNewton and it means named placeholders can be used。PHPで連結する場合、名前付きプレースホルダーの問題でさえありますか?PHPでの連結は、名前付きと位置の両方をサポートし、どのデータベースでも同じクエリを使用できるため、移植性が高くなります。これほど多くの人々があると思いますなぜ私は本当に理解していない任意の名前を付けて位置プレースホルダの違いは。
常識

18
$query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
$query->bindValue(1, "%$value%", PDO::PARAM_STR);
$query->execute();

if (!$query->rowCount() == 0) 
{
    while ($results = $query->fetch()) 
    {
        echo $results['column'] . "<br />\n";
    }       
} 
else 
{
    echo 'Nothing found';
}

1
受け入れられた答えよりもこれを使用する利点はありますか?を使用bindValueしてインジェクション攻撃から保護しますか?受け入れられた答えは基本的に、昔のような?検索文字列を連結することでプレースホルダーを使用することの価値を否定します%
15:13にfelwithe

$ query-> rowCount()== 0の前に否定を使用する意味は何ですか?これは実際に意味がありますか?
ssi-anik 2015

14

こちらもお試しいただけます。同様の問題に直面しましたが、研究の結果、結果が出ました。

$query = $pdo_connection->prepare('SELECT * FROM table WHERE column LIKE :search');

$stmt= $pdo_connection->prepare($query);

$stmt->execute(array(':search' => '%'.$search_term.'%'));

$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

print_r($result);

投稿を編集してコードをコードブロックに入れました。投稿のフォーマットについて詳しくは、stackoverflow.com / help / formattingをご覧ください。他のユーザーがコメントを残さずに回答に反対票を投じることを選択したため、反対票の原因はわかりません。
josliber

2
繰り返しになりますが、私はあなたの質問に投票しませんでした。他の誰かが反対票を投じた。
josliber

3

これは機能します:

search `table` where `column` like concat('%', :column, '%')

2

私はこれをPHPの妄想から手に入れた

$search = "%$search%";
$stmt  = $pdo->prepare("SELECT * FROM table WHERE name LIKE ?");
$stmt->execute([$search]);
$data = $stmt->fetchAll();

そして、それは私にとってはとても簡単に機能します。彼が言うように、クエリに送信する前に「最初に完全なリテラルを準備する」必要があります


0

PDOは(SQLインジェクションにつながる可能性があり)「%」をエスケープ:前のコードの使用は、所望の結果が得られます一部の文字列を一致させるために探しているときしかし、文字「%」ビジタータイプならば、あなたはドン場合でも、あなたはまだ」の結果が得られますtデータベースに何かが保存されている(SQLインジェクションを引き起こす可能性がある)

PDOが「%」をエスケープして不要な/興奮していない検索結果を導き、同じ結果でさまざまなバリエーションを試しました。

誰かがそれについての言葉を見つけたら共有する価値がありましたが、共有してください


1
これは、マニュアルからです:us3.php.net/manual/en/pdo.prepared-statements.php これは、件名に関する別の投稿です:stackoverflow.com/questions/22030451/… 私は本当にあなたの意見を知りたいですこの問題。
Ozkar R 2015

1
可能な解決策(テストされていません)次のようにCONCATを使用します。$ sql =“ SELECT item_title FROM item WHERE item_title LIKE CONCAT( '%'、?、 '%')”; 参照:blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard
Ozkar R

3
PDOは%をエスケープしません。それが間違っているのはあなたのコードです。ソリューションについては、ここですでに提供さ
常識

提案ありがとうございます。とにかく、テストされたコードは、SQLインジェクションを回避するためにプレースホルダーを使用して、マニュアルのコードでした。それでも同じ結果が得られます。例6プレースホルダー PDOの無効な使用は、コードではなく、上記のコードを使用して%エスケープします。私はフォーラムに不慣れです。コメント、投稿、評判のプロセスがここでどのように機能するのか理解できないかもしれません。次のことは覚えておきます。以前のコメントに基づいて、他の人を助けるかコメントを書くには評判が必要だからです。ありがとう。
Ozkar R
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.