2009-11-23 15 views
40

PHPのPDOクラス(mysqlドライバ)で検索しようとしています。私は(テーブル名は無実を保護するために変更された)MySQLクライアントでの作業次のクエリを持っている:PHP PDO準備文 - MySQL LIKEクエリ

SELECT hs.hs_pk, 
      hs.hs_text, 
      hs.hs_did, 
      hd.hd_did, 
      hd.hd_text, 
      hv.hv_text, 
      hc.hc_text 
FROM  hs 
LEFT JOIN hd 
ON  hs.hs_did = hd.hd_did 
LEFT JOIN hd 
ON  hd.hd_vid = hv.hv_id 
LEFT JOIN hc 
ON  hd.hd_pclass = hc.hc_id 
WHERE  hs.hs_text LIKE "%searchTerm%" 
LIMIT 25; 

これは関係なく、私が使用する検索用語の魔法のように動作します。しかし、私はPHPに移動すると、私は何かを返すようにすることはできません。論理的に見えるいくつかの構文を試しましたが、何も試したことがありません。私は(句&分取を>実行行はすべてその変更をされているSQL)だけでなく、次の試してみた

$handle = fopen('/foo/bar/test.log', 'w+'); 
fwrite($handle, "doSearch, with search term: $searchTerm\n"); 
$sql = 
'SELECT hs.hs_pk, 
      hs.hs_text, 
      hs.hs_did, 
      hd.hd_did, 
      hd.hd_text, 
      hv.hv_text, 
      hc.hc_text 
FROM  hs 
LEFT JOIN hd 
ON  hs.hs_did = hd.hd_did 
LEFT JOIN hd 
ON  hd.hd_vid = hv.hv_id 
LEFT JOIN hc 
ON  hd.hd_pclass = hc.hc_id 
WHERE  hs.hs_text LIKE :searchTerm 
LIMIT 25'; 

try { 
$dbh = new PDO('mysql:host=localhost;dbname=awdb', "user", "password"); 
fwrite($handle, "connected to DB\n"); 
$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array(':searchTerm' => '"%'.$searchTerm.'%"')); 

while ($row = $prep->fetch(PDO::FETCH_ASSOC)) { 
    $i++; 
    $result[$i]['subText'] = $row['hs_pk']; 
    $result[$i]['subText'] = $row['hs_text']; 
    $result[$i]['subDid'] = $row['hs_did']; 
    $result[$i]['devDid'] = $row['hd_did']; 
    $result[$i]['devText'] = $row['hd_text']; 
    $result[$i]['vendorText'] = $row['hv_text']; 
    $result[$i]['classText'] = $row['hc_text']; 
} 
    $dbh = null; 
} 
catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

:ここに私の既存のコードです

WHERE hs.hs_text LIKE CONCAT(\'%\', ?, \'%\') 
$ret = $prep->execute(array($searchTerm)); 

WHERE hs.hs_text LIKE "%:searchTerm%" 
$ret = $prep->execute(array(':searchTerm' => $searchTerm)); 

WHERE hs.hs_text LIKE ":searchTerm" 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

等...

+1

それはちょうど転置の問題かもしれないが、あなたは、SQL文を同封していない - あなたは、アポストロフィ( ')を配置する必要がありますそれの終わりに。 –

+0

転置の問題でした。もし私が忘れてしまったのは、PHPが完全に驚いたのは確かです。しかし、非常に迅速な返信をありがとう。 – TIm

+1

var_dump()$ dbh、$ prep、$ retのときはどうなりますか?彼らはあなたが期待する価値ですか?比較のためにmysql_ *ファミリーの関数を使って同じクエリを実行しようとしましたか?ここ – jkndrkn

答えて

93
$ret = $prep->execute(array(':searchTerm' => '"%'.$searchTerm.'%"')); 

これは間違っています。二重引用符は必要ありません。

WHERE hs.hs_text LIKE ":searchTerm" 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

これも間違っています。 で試してみてください:

$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

説明:プリペアドステートメントは、単に文字列は、置き換えるいたしません。彼らは、クエリから完全に分離してデータを転送します。クォートは、クエリに値を埋め込む場合にのみ必要です。

+0

その説明をありがとう。この問題は解決しないかもしれませんが、将来のために私の記憶に残しておきます。 – TIm

+26

@ Tlmあなたはまだ彼の答えを受け入れるべきです。直接提供されるようにあなたの質問に答えます。それはあなたに何も受け入れられません。 –

-5

さて、私はこれを解決しました。そして、率直に言って、私はばかです...これを見て、良いフィードバックをいただき、ありがとうございます。問題は、テーブル名のタイプミス(私は変更されたので、ここで誰も私の問題を最初から見ることができません...)。提案は私に問題を見つけるように導いてくれました。しかし、あなたにはadam、jkndrkn、troelsknに感謝します。

レコードの

、以下の組み合わせがうまく機能:

WHERE aw_hcl_subdevices.hs_text LIKE CONCAT(\'%\', ?, \'%\') 
$ret = $prep->execute(array($searchTerm)); 
+14

-1これはこれを行う正しい方法ではありません。特定のタイプのSQLインジェクション(私は名前を忘れる)まであなたを開きますので、3つの静的*文字列リテラルに対してCONCAT()を使用しないでください。 –

+4

ダンノは誰も、上記のコメントをupvotedこれらの人々ですが、不思議なことに - 誰も注射の名前を管理することはできませんでした。おそらく、そのような「注入」は決して存在しなかったからでしょう。 –

+0

@ TheodoreR.Smithから聞いてみたいと思っています。 [詳細については、この個別の質問](http://stackoverflow.com/questions/22740375/why-should-you-not-use-concat-for-static-string-literals) – Prix

-2
$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array('searchTerm' => $searchTerm)); 
+4

このアンサーは完全ではありません($ sqlを参照しますか?)、いくつかの情報が間違っています( "LIKE '%FOO%'"の検索方法)。このように置かれたいくつかのコードは、答えではなく、IMOは文脈から外れているだけです。 – Redips77