问题 PHP PDO - 绑定表名? [重复]


这个问题在这里已有答案:


10667
2018-03-03 05:54


起源



答案:


是否可以绑定表名?

没有。

您必须将表名称列入白名单。我怀疑你想让用户浏览 任何 数据库中的表。

而且您还必须手动格式化标识符。 有一个 标签维基 用例子。为什么不先读它?

更新: 正如您所看到的,PDO对于现实生活任务来说是不方便的。 因此,您必须拥有一个更智能的抽象库来处理MySQL查询。 这是一个使用的例子 safeMysql class,这将使您的代码显着缩短:

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;
    }
}

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


10
2018-03-03 05:57



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


答案:


是否可以绑定表名?

没有。

您必须将表名称列入白名单。我怀疑你想让用户浏览 任何 数据库中的表。

而且您还必须手动格式化标识符。 有一个 标签维基 用例子。为什么不先读它?

更新: 正如您所看到的,PDO对于现实生活任务来说是不方便的。 因此,您必须拥有一个更智能的抽象库来处理MySQL查询。 这是一个使用的例子 safeMysql class,这将使您的代码显着缩短:

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;
    }
}

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


10
2018-03-03 05:57



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


有一个PDO包装类 - http://www.phpclasses.org/package/5997-PHP-Database-access-abstraction-layer.html 这可以让你这样做(虽然我是PDO的新手所以也许它不是使用准备好的语句)

他的建议用法是:

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

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

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


2
2018-03-03 06:42



无论什么班级做事 filterForSql 是不可用的危险垃圾。该网站需要注册,因此,我无法进行更全面的审核 - Your Common Sense
当你没有阅读源代码时,我很惊讶你说它是无法使用的垃圾。对不起,但有一些相互矛盾的信息,我有兴趣看到'防弹PDO数据库课' - 你有什么建议吗? - acutesoftware
你发布的功能绰绰有余。 SQL查询包含 许多 不同的部分,并且不可能为它们创建一个共同的过滤器 - 过滤一个将打破另一个和相反。我有一个用于运行mysql查询的防弹类(虽然不是基于PDO,但没关系)。您可以在我的个人资料中找到该链接。我知道的唯一真正的防弹课程。 - Your Common Sense
感谢上课 - 看起来很有趣。我仍然不相信原始的海报请求不能满足。 - acutesoftware
我已将代码添加到我的答案中。 - Your Common Sense