使用 PDO 准备好的语句 MySQL 错误

Posted

技术标签:

【中文标题】使用 PDO 准备好的语句 MySQL 错误【英文标题】:Using PDO prepared statements MySQL error 【发布时间】:2016-01-12 20:39:32 【问题描述】:

我正在尝试在 php 中创建一个 OOP 风格的 CRUD 类,并使用 PDO 准备好的语句来防止注入。我的连接正常,我可以从类中执行常规 SQL 查询,但是当我尝试合并 PDO 的准备函数时,我收到一个错误,我有一个 mysql 语法错误或 PDO 准备未定义。

错误在$p_query = $db->prepare($sql) 行被抛出。谁能发现我做错了什么?

<?php
require_once 'dbconfig.php';

class Crud 
    protected $db;

    private static function fetchQuery($sql, $values) 
        echo $sql;
        var_dump($values);
        $db = Db_conn::pdoBuilder();
        $p_query = $db->prepare($sql);
        $p_query->execute($values);
        $results = $p_query->fetch(PDO::FETCH_OBJ);
        return $results;    
    
    public static function show($tbl, $id) 
        $sql = '"SELECT * FROM (:tbl) WHERE id = (:id)"';
        $values = [':tbl' => $tbl, ':id' => $id];
        $results = self::fetchQuery($sql, $values);
        return $results;

    

    public static function listAll($tbl) 
        $sql = '"SELECT * FROM (:tbl)"';
        $values = [':tbl' => $tbl];
        $results = self::fetchQuery($sql, $values);
        return $results;
    

【问题讨论】:

向我们展示$sql$values的输出 您是否尝试从查询中删除双引号?从表名和列过滤器中删除括号怎么样? @MarcoAurélioDeleu sql: "SELECT * FROM (:tbl)" values: array(1) [":tbl"]=> string(6) "client" 表名不能参数化。准备好的语句基本上是部分查询,其中缺少的只是 where 子句或 VALUES (在插入的情况下)中的数据\ 【参考方案1】:

首先:

$sql = '"SELECT * FROM ?"';

您为什么要引用您的查询?应该是:

$sql = 'SELECT * FROM ?';

下一步:

$values = [':tbl' => $tbl];

查询中的占位符 :tbl 在哪里?您正在使用?,请将$sql 字符串更改为:

$sql = 'SELECT * FROM :tbl';

这立即带来了另一个问题:您在准备好的语句中使用的表在您创建准备好的语句后无法绑定。不可能。永远不会发生。您可以做的最好的事情是:

$sql = sprintf(
    'SELECT * FROM `%s`',
    //remove illegal chars
    str_replace([' ', '\\', '`', '"', "'"], '', trim($tbl))
);

最后,应用于这个位:

$sql = '"SELECT * FROM (:tbl) WHERE id = (:id)"';
$values = [':tbl' => $tbl, ':id' => $id];
$results = self::fetchQuery($sql, $values);

这意味着你必须写:

$sql = sprintf(
    'SELECT * FROM `%s` WHERE id = :id',
    $tbl
);
$values = [':id' => $id];
return self::fetchQuery($sql, $values);

但实际上,您并没有尽可能地使用准备好的语句。准备好的语句最好的一点是它们是可重用的。据我所知,包装PDO 以获得更清洁的API 尚未完成。大多数尝试实际上是为了削弱扩展的力量,或者围绕它构建一个臃肿的抽象层。如果您正在构建一个成熟的 ORM/DBAL,那不一定是坏事。 I've been quite vocal about this stuff here,你可能想通读一遍

【讨论】:

以上是关于使用 PDO 准备好的语句 MySQL 错误的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 全文连字符和大括号返回错误(最初:PDO 准备好的语句没有做它的工作?)

PDO 是不是仍在为 MySQL 模拟准备好的语句?

从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?

在 PHP 中到处使用准备好的语句? (PDO)

PDO - 使用准备好的语句[重复]

用 PDO 和准备好的语句替换 mysql_* 函数