使用PHP PDO进行动态查询

3 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();
Run Code Online (Sandbox Code Playgroud)

但是如果我没有选择任何字段并希望显示整个历史记录,则这不起作用.

使用mysql_query()我会这样做:

mysql_query('SELECT date,
                    name,
                    action
             FROM history
             $Name
             $Action');
Run Code Online (Sandbox Code Playgroud)

这意味着如果没有$ Name或$ Action,它们就不会包含在查询中.

我应该只将旧查询复制/粘贴到$ q = $ db-query('')中吗?但这种方式违背了使用PDO的目的.

nik*_*org 10

您始终可以将默认值分配给符合列名称的参数.

这样,您的查询将在默认情况下结束,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();
Run Code Online (Sandbox Code Playgroud)

在这个例子中,empty检查可以在我们完成sql语句的循环中完成,但是这会给你一个不那么一般的例子.

此示例还省略了类型参数bindValue,但这可以很容易地实现,例如通过将数组值更改为具有类型作为成员的对象或数组,或者通过在分配循环内进行鸭子键入.

只要您提供初始(一般情况)查询以及params数组,查询构建就可以以这种形式轻松放入适用于所有数据库查询需求的函数中.