динамический — PHP / PDO Динамически связываемые значения (ошибка подсчета неверных параметров)

Мне было поручено (застряло) попытаться обновить старый код mysql_query для обеспечения совместимости с PDO.

Это была (является) грязная форма поиска, которая динамически создавала строку запроса на основе значений поля, если (или нет) были какие-либо ключевые слова, отправленные вместе с формой. (то есть: любое ключевое слово анализируется пробелами и используется для поиска в обоих столбцах)

Так что, если был введен поисковый термин «собака» … он будет искать имя & название для ключевого слова «собака» ..

Я думаю, что я прошел через это … по большей части оставив в силе основные «функции» … и обновляя их, когда мне было нужно.

Мой подход состоял в том, чтобы взять функцию, которая динамически добавляет больше критериев в строку запроса …., а также добавить это имя поля значения & значение в массиве, так что я могу позже просмотреть его и динамически связать с ним.

Я теперь придерживаюсь очень популярной ошибки Invalid Parameters !!

Однако его не говорит, что количество не совпадает .. это говорит, что это было определено вообще.

Мне не ясно, откуда возникла моя ошибка .. (или как легко увидеть вычисленную / проанализированную строку запроса .. или фактические связанные параметры). Я могу просто вывести оператор sql (до того, как он проанализирует какие-либо данные) .. или выведите мои значения в массив, который я перебираю, чтобы (потенциально) связать данные с вызовом PDO ..

Когда я повторяю запрос (строку) .. и даже значения, которые я пытаюсь динамически связать … все они выглядят законно для меня:

Query Check: SELECT * FROM pid_information WHERE 1=1 AND (((title LIKE :title0) OR (name LIKE :name0)) AND ((title LIKE :title1) OR (name LIKE :name1))) ORDER BY title, name, link
PARAM CHECK: ':title0' -> %cat%
PARAM CHECK: ':name0' -> %cat%
PARAM CHECK: ':title1' -> %dog%
PARAM CHECK: ':name1' -> %dog%

Чтобы перефокусировать:
Функция addCriteria () используется для динамического (concat) добавления к запросу «строка»

Я также заполняю массив для последующего использования в цикле и связывания с bindValues.

Да, я знаю, это долго .. да, я знаю, некрасиво .. (пожалуйста, просто терпите меня!) LOL

//dynamically add criteria to query
$boundSearchValues = array();
function addCriteria($targetFields, $criteriaString, $targetOperator='LIKE'){
global $boundSearchValues;
$fieldCount = 0;
$tempString = "";
if($criteriaString != ""){
$criteriaArray = explode(" ", $criteriaString);
$tempString .= " AND (";
foreach($criteriaArray as $criteriaIndex => $criteriaValue){
//is array of fields
if(is_array($targetFields)){
$tempString .= "(";
foreach ($targetFields as $targetField => $fieldName){
if($targetOperator != 'LIKE') {
$tempString .= "($fieldName ".$targetOperator." :". $fieldName.$fieldCount .")";
$boundSearchValues[] = [$fieldName.$fieldCount, $criteriaValue];
}else{
$tempString .= "($fieldName LIKE :". $fieldName.$fieldCount .")";
$boundSearchValues[] = [$fieldName.$fieldCount, '%'.$criteriaValue.'%'];
}
if($targetField+1 < count($targetFields)){
$tempString .= " OR ";
}
}
$tempString .= ")";
if($criteriaIndex+1 < count($criteriaArray)){
$tempString .= " AND ";
}

//not an array of fields
}else{
if($targetOperator != 'LIKE') {
$tempString .= "(".$targetFields . $targetOperator . " :" . $fieldName.$fieldCount . ")";
$boundSearchValues[] = [$fieldName.$fieldCount, $criteriaValue];
} else {
$tempString .= "(". $targetFields . " LIKE " . $fieldName . $fieldCount . ")";
$boundSearchValues[] = [$fieldName.$fieldCount, '%'.$criteriaValue.'%'];
}
}

$fieldCount++; //increment counter
}
$tempString .= ")";

}
return $tempString;
}

//start serach query
$searchDetails_sql = "SELECT * FROM $tablename ";
//dynamically update query string
if($clean_keywords != "") {
$whereClause = addCriteria(array('title', 'name'), $clean_keywords);
}else{
if($title != "" && $title != "all"){
$whereClause .= " AND title = :" . $title;
}
if($name != "" && $name != "all"){
$whereClause .= " AND name = :" . $name;
}
if($link != "" && $link != "all"){
$whereClause .= " AND link = :" . $link ;
}
}
$searchDetails_sql .= "WHERE 1=1 ". $whereClause;
$searchDetails_sql .= " ORDER BY title, name, link";
$searchDetails_stmt = $conn->prepare($searchDetails_sql);

//dynamically bind values
for($i=0; $i<count($boundSearchValues); $i++){
$searchDetails_stmt->bindValue("':".$boundSearchValues[$i][0] ."'", $boundSearchValues[$i][1]);
//$searchDetails_stmt->bindParam("':".$boundSearchValues[$i][0] ."'", $boundSearchValues[$i][1]);
echo '<br>PARAM CHECK: ' . $boundSearchValues[$i][0] . " / " .  $boundSearchValues[$i][1];
}
$searchDetails_stmt->execute();
$searchDetails_stmt->setFetchMode(PDO::FETCH_ASSOC);
$searchDetails = $searchDetails_stmt->fetchAll(); //returns multi-dimensional array (and correct count)

1

Решение

Я думаю, что вы только что испортили конкатенацию строк в этой строке

$searchDetails_stmt
->bindValue("':".$boundSearchValues[$i][0] ."'", $boundSearchValues[$i][1]);

Вам на самом деле не нужно : чтобы ты мог сделать это

$searchDetails_stmt
->bindValue($boundSearchValues[$i][0], $boundSearchValues[$i][1]);

Или исправить сцепление и сохранить :

$searchDetails_stmt
->bindValue(":".$boundSearchValues[$i][0], $boundSearchValues[$i][1]);
2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector