【问题标题】:Using PDO prepared statements MySQL error使用 PDO 准备好的语句 MySQL 错误
【发布时间】: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 (在插入的情况下)中的数据\

标签: php mysql pdo


【解决方案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,你可能想通读一遍

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 2017-04-05
    • 2012-11-13
    • 2017-09-29
    相关资源
    最近更新 更多