PHP PDO - 绑定表名? [复制]

Posted

技术标签:

【中文标题】PHP PDO - 绑定表名? [复制]【英文标题】:PHP PDO - Bind table name? [duplicate] 【发布时间】:2013-02-17 10:34:09 【问题描述】:

可以绑定表名吗?

我想创建一个类来读取表中的列,并根据字段类型为我生成表单输入。当我执行$form = new form("users"); 时,构造函数应该从使用以下代码从表中获取字段名称开始:

class form

    public function __construct($table, $skip = array("id"))
        $pdo = new PDO('mysql:host=localhost;dbname=site;',USER,PASS);

        $query = $pdo->prepare("DESCRIBE :table");

        $query->bindValue(':table', $table, PDO::PARAM_STR, strlen($table));

        $query->execute();

        while($field = $query->fetch(PDO::FETCH_NUM))
            var_dump($field);
            echo "<br /><br />";
        

        unset($pdo);
    

当我在prepare语句中指定“users”而不是“:table”时,这工作得很好,但是绑定它正在工作,我很确定这是因为它试图绑定一个表名。此外,这需要绑定,因为我希望能够通过$_GET 等传递我的表名。

【问题讨论】:

【参考方案1】:

可以绑定表名吗?

没有。

您必须将表名列入白名单。我怀疑您是否想让用户从您的数据库中浏览 any 表。

您还必须手动格式化标识符。 有一个tag wiki 的例子。为什么不先读呢?

更新: 如您所见,PDO 对现实生活中的任务不方便。 所以,你必须有一个更智能的抽象库来处理 MySQL 查询。 下面是一个使用 safeMysql 类的示例,这将使您的代码大大缩短:

class form
    public function __construct($table)
        global $db;
        return $db->getAll("DESCRIBE ?n", $table);
    

2 个注释:

我删除了第二个参数,因为您的函数中没有使用它的代码。 永远不要在课堂上进行连接。请改用已打开的连接。或者你会用这么多的连接杀死你的 MySQL 服务器。

排除实施的版本

class form 
    public function __construct($table,$skip = array("id"))
        global $db;
        $data = array();
        $res = $db->query("DESCRIBE ?n", $table);
        while($row = $db->fetch($res)) 
            if (!in_array($row['Field'],$skip)) 
                $data[] = $row;
            
        
        return $data;
    

然而,这样的类很少能按预期使用 - 总是有很多例外和手动格式化以使其可用。

【讨论】:

在那个wiki的'PDO Prepared statements and IN'部分,你为什么不能用表的参数替换SQL字符串? 我不知道有标签维基。这很方便。还有,为什么这样的课会浪费时间? 完成所有编辑后,您的答案更有意义。我将坚持使用一个简单的、无绑定的 PDO 查询,因为它会使用与您提到的类相同数量的语句,并创建一个全局 pdo 变量。此外,该类不是为了让表单从头到尾,它只是为了使用正确的输入类型为您创建输入和标签,使用正确的“for”标签,输入的最大长度等于数据库中字段的最大长度等。就格式而言,只要您保持 html 简单,所有格式都可以在 CSS 中轻松完成。 @MisterMelancholy 如果它采用完全相同数量的语句,则您没有格式化 $table 变量,因此允许注入。 是的。 “您不想让用户选择他们看到的表格”还有另一个好处。如果我需要将表名列入白名单,我不需要在比较之前清理变量,因为如果它与白名单表名不完全匹配,SQL 查询将不会运行,因此不需要SQL 清理。很抱歉在我之前的评论中跳过了那个小细节。【参考方案2】:

在http://www.phpclasses.org/package/5997-PHP-Database-access-abstraction-layer.html 有一个 PDO 包装类,可以让您执行此操作(虽然我是 PDO 新手,所以它可能没有使用准备好的语句)

他的建议用法是:

 $db = new DatabaseConnection('someMysqlServer', 'user', 'pass', 'database');

 $result = $db->exec($db->filterForSql('SELECT * FROM '.$tableName.';'));

如果其他人认为这是使用 PDO 的“安全”方式,我会很感兴趣。

【讨论】:

无论什么班级做像filterForSql 这样的事情都是不可用的危险废话。该网站需要注册,因此我无法更全面地查看它 我很惊讶你说当你没有阅读源代码时它是无法使用的废话。抱歉,这方面有很多相互矛盾的信息,我有兴趣看到一个“防弹 PDO 数据库类”——你有什么建议吗? 您发布的功能足以判断。 SQL 查询由许多 个不同的部分组成,不可能为它们创建一个通用的过滤器——过滤一个会破坏另一个,相反。我有一个用于运行 mysql 查询的防弹类(虽然不是基于 PDO,但没关系)。您可以在我的个人资料中找到该链接。我所知道的唯一真正的防弹类。 感谢您的课程 - 看起来很有趣。我仍然不相信原始海报要求无法满足。 我已将代码添加到我的答案中。

以上是关于PHP PDO - 绑定表名? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

PDO 调试 - 绑定后查看查询? [复制]

在 PHP 中将十进制/双精度/浮点值与 PDO 绑定的最佳方法是啥?

php pdo 参数绑定

如何使用 PDO 在 PHP 中绑定 bigint 值?

PHP PostgreSQL PDO 无法使用 LIKE 绑定参数

PHP MySQL PDO 绑定输入/输出相同参数