使用PHP-PDO的动态查询

使用PHP-PDO的动态查询,php,pdo,Php,Pdo,我正试图找出如何将我的历史脚本从mysql_query()转换为PDO。我有一个表单,有4个输入字段,你可以随机选择。这意味着根据您试图获取的信息,可以选择0、1、2、3、4个字段 我尝试过这样查询数据库: $q = $db->prepare('SELECT date, name, action FROM history

我正试图找出如何将我的历史脚本从mysql_query()转换为PDO。我有一个表单,有4个输入字段,你可以随机选择。这意味着根据您试图获取的信息,可以选择0、1、2、3、4个字段

我尝试过这样查询数据库:

$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的目的。

您可以始终为符合列名的参数指定默认值

这样,在默认情况下,您的查询将以
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 to
bindValue
,但这很容易实现,例如,通过将数组值更改为具有该类型作为成员的对象或数组,或者通过在赋值循环中键入duck


这种形式的查询构建可以很容易地放入一个函数中,该函数可以满足所有数据库查询需求,只要您提供初始(一般情况)查询以及params数组

如果变量为空,我尝试只添加一个空格。不起作用。空格是一个值,因此只能匹配包含该值的列,但列始终会匹配自身。我在phpmyadmin中尝试了您的解决方案,效果非常好。现在唯一的问题是,当我使用bindParam时,它们会被包含在“”中,而“”不是列,而是搜索词。有没有办法删除这些“”?当我绑定它时,我正在使用PDO::PARAM_STR。@eSiks:噢,天哪。我的逻辑有一个明显的错误,我更新了我的答案:-)谢谢你以非常理解的方式向我解释这一点。它完全按照它应该的方式工作。我将对每一个带有非静态变量的搜索算法使用这种方法。