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 - 绑定表名? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
在 PHP 中将十进制/双精度/浮点值与 PDO 绑定的最佳方法是啥?