Динамические запросы с PHP PDO - PullRequest
3 голосов
/ 27 декабря 2010

Я пытаюсь выяснить, как преобразовать мой скрипт истории из 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.

1 Ответ

10 голосов
/ 27 декабря 2010

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

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

EDIT:

Конечно, моя логика была слегка ошибочной, поскольку 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, но это дало бы вам менее общий пример.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...