Re: [請益] 想請問一下關於pdo搜尋多組字串的問題

作者: anawak (...)   2017-02-11 22:56:35
※ 引述《rjackie (向前走,才知道轉角)》之銘言:
: <?php
: $keys = explode(" ",$_GET['p_search']);
: $term = "%".$_GET['p_search']."%";
: foreach ($keys as $word) {
: $search_name[] = 'product_info.name LIKE ?';
: $search_summary[] = 'product_info.summary LIKE ?';
: $search_model[] = 'product_standard_data.model LIKE ?';
: $arguments[] = '%'.$word.'%';
:
: }
: $product_info_auto_sql = $db->prepare("
: SELECT
: product_info.name
: FROM
: product_info,product_standard_data
: WHERE
: product_info.no = product_standard_data.product_no
: AND
: ".implode(' AND ', $search_name)."
: OR
: ".implode(' AND ', $search_summary)."
: OR
: ".implode(' AND ', $search_model)."
: AND
: product_info.status = '1' GROUP BY product_info.name order by product_in
: fo.sequence DESC, product_info.name DESC");
: $product_info_auto_sql->execute($arguments);
: while($product_info_auto_row = $product_info_auto_sql->fetch()){
: echo $product_info_auto_row['name'];
: }
: ?>
:
: 問題在於無法在execute的時候會發生
: Invalid parameter number: number of bound variables does not match number
: 有嘗試過arguments使用三次當然一定會錯,或是將$term變成陣列方式但還是有問題。
: 不知道這情況是否有什麼建議作法呢?
: 感恩
你的WHERE字串,串起來後好像都沒有括號?
只看到 implode 的括號,但是字串串起來後,應該是沒有括號。
類似 WHERE condA1 AND condA2 OR condB1 AND condB2 OR condC1 AND cond C2 ...
一堆AND跟OR擠在一起,這樣有問題吧。
應該改成
WHERE
(product_no=123 AND status=1)
AND (
(condA1 AND condA2) /*search_name*/
OR (condB1 AND condB2) /*search_summary*/
OR (condC1 AND condC2) /*search_model*/
)
而且可以使用名稱變數,不使用問號。
SELECT ... WHERE col1=:col1 AND col2=:col2
下面只使用 search_name 跟 search_model , 僅供參考。
foreach ($keys as $key=>$word) {
$search_name[] = 'product_info.name LIKE :word' . $key;
/*
$search_name = array(
'product_info.name LIKE :word1',
'product_info.name LIKE :word2',
...
);
*/
$search_model[] = 'product_standard_data.model LIKE :word' . $key;
/*
$search_model = array(
'product_standard_data.model LIKE :word1',
'product_standard_data.model LIKE :word2',
...
);
*/
}
$whName = implode(' AND ', $search_name);
//product_info.name LIKE :word1 AND product_info.name LIKE :word2
$whModel = implode(' AND ', $search_model);
//類似上面
$sql = "
SELECT ...
WHERE
(info.no = standard_data.product_no AND info.status = '1')
AND (
(" . $whName . ")
OR (" . $whModel . ")
OR (" . $whSummary . ")
)
";
$result = $dbh->prepare($sql);
foreach($keys as $key=>$word){
$keystr = 'word' . $key; //word1, word2...
$$keystr = $word; //注意符號是兩個
$result->bindParam(':'.$keystr, $$keystr);
}
$result->execute();
我之前寫過的大概是這樣。
會用兩個符$符號,記得是因為 bindParam 使用的變數不允許重複。
因為 bindParam 的意思就是把變數跟值綁定在一起,
綁定了,就不能改,所以不能跑迴圈。
$$keystr 會先變成 $word1 或 $word2, 然後值就是該次的 $word
不保證成功,可能要再多測試。
作者: rjackie (向前走,才知道轉角)   2017-02-11 23:16:00
哇!感謝經驗分享,其中很多是沒有想到的概念,我研究一下
作者: MOONRAKER (㊣牛鶴鰻毛人)   2017-02-11 23:29:00
可以用assoc array 就不用$$了
作者: mimikillua   2017-04-25 17:05:00
"bindParam 使用的變數不允許重複"這句幫大忙了我用同一個變數搜尋不同column 怎樣改都出錯

Links booklink

Contact Us: admin [ a t ] ucptt.com