Динамические запросы с PHP PDO

Я пытаюсь понять, как преобразовать свой сценарий истории из mysql_query () в PDO. У меня есть форма с 4 полями ввода, которые вы можете произвольно выбрать. Это означает, что в зависимости от того, какую информацию вы пытаетесь получить, вы можете выбрать 0, 1, 2, 3, 4 поля.

Я попытался запросить db следующим образом:

$q = $db->prepare('SELECT date, name, action FROM history WHERE name = :name AND action = :action'); $q->bindParam(':name', $Name, PDO::PARAM_STR, 20); $q->bindParam(':action', $Action, $PDO::PARAM_STR, 20); $q->execute(); 

Но это не работает, если у меня нет выбранных полей и вы хотите, чтобы вся история была показана.

С mysql_query () я бы просто сделал это:

 mysql_query('SELECT date, name, action FROM history $Name $Action'); 

Это означает, что если нет $ Name или $ Action, они просто не включены в запрос.

Должен ли я просто скопировать / вставить старый запрос в $ q = $ db-query ('')? Но этот вид поражения использует PDO.

Solutions Collecting From Web of "Динамические запросы с PHP PDO"

Вы всегда можете присваивать значения по умолчанию параметрам, которые соответствуют именам столбцов.

Таким образом, ваш запрос будет в случае по умолчанию заканчиваться как where column = column и когда будет присутствовать значение, это будет where column = value .

РЕДАКТИРОВАТЬ:

Конечно, моя логика была немного ошибочной, поскольку bindParam не работает именно так. Вместо этого вы должны постепенно создавать свою инструкцию в соответствии с набором параметров.

 /* Start with the most general case for the sql query. * The where part always evaluates to true and will thus * always return all rows and exists only to make appending * further conditions easier. */ $q = 'SELECT date, name, action FROM history WHERE 1'; /* Prepare a params array in any way you wish. A loop might be more * efficient if it is possible, but since in this example you have * only 2 variables, it didn't seem necessary */ $params = array(); if (! empty($Name)) { $params['name'] = $Name; } if (! empty($Action)) { $params['action'] = $Action; } /* When the params array is populated, complete the sql statement by * appending the param names joined with ANDs */ foreach ($params as $key => $value) { $q .= sprintf(' AND `%s` = :%s', $key, $key); } /* When the query is complete, we can prepare it */ $stmt = $db->prepare($q); /* Then bind the values to the prepared statement */ foreach ($params as $key => $value) { // Using bindValue because bindParam binds a reference, which is // only evaluated at the point of execute $stmt->bindValue(':'.$key, $value); } /* Now we're ready to execute */ $stmt->execute(); 

В этом примере empty проверка могла быть выполнена в цикле, где мы завершаем инструкцию sql, но это дало бы вам менее общий пример.

В этом примере также исключается тип param для bindValue , но это было бы легко реализовано, например, путем изменения значения массива на объект или массив, имеющие тип в качестве элемента, или путем утиного ввода внутри цикла назначения.

Создание запроса в этой форме легко можно было бы включить в функцию, которая будет работать для всех запросов на запросы к базе данных, если вы предоставите ей исходный (общий случай) запрос вместе с массивом params.