4 回答
![?](http://img1.sycdn.imooc.com/5458471300017f3702200220-100-100.jpg)
TA贡献1794条经验 获得超7个赞
表和列名称不能由PDO中的参数替换。
在这种情况下,您只需手动过滤和清理数据。一种方法是将速记参数传递给将动态执行查询的函数,然后使用switch()
语句创建用于表名或列名的有效值的白名单。这样,用户输入就不会直接进入查询。例如:
function buildQuery( $get_var ) { switch($get_var) { case 1: $tbl = 'users'; break; } $sql = "SELECT * FROM $tbl";}
通过不保留默认情况或使用返回错误消息的默认情况,您可以确保仅使用您想要使用的值。
![?](http://img1.sycdn.imooc.com/533e4bd900011a1d02000200-100-100.jpg)
TA贡献1876条经验 获得超5个赞
要理解为什么绑定表(或列)名称不起作用,您必须了解预处理语句中的占位符如何工作:它们不是简单地替换为(适当转义的)字符串,而是执行生成的SQL。相反,DBMS要求“准备”一个语句会提供一个完整的查询计划,以确定它将如何执行该查询,包括它将使用哪些表和索引,无论您如何填充占位符,这些表和索引都是相同的。
SELECT name FROM my_table WHERE id = :value
无论你替换什么,计划都是一样的:value
,但看似相似SELECT name FROM :table WHERE id = :value
无法计划,因为DBMS不知道你实际上要从哪个表中选择。
这不是PDO之类的抽象库可以或应该解决的问题,因为它会破坏预准备语句的两个关键目的:1)允许数据库提前决定如何运行查询,并使用相同的方法计划多次; 2)通过将查询逻辑与变量输入分开来防止安全问题。
![?](http://img1.sycdn.imooc.com/54584d080001566902200220-100-100.jpg)
TA贡献1833条经验 获得超4个赞
我看到这是一个旧帖子,但我发现它很有用,并且我认为我会分享一个类似于@kzqai建议的解决方案:
我有一个函数接收两个参数,如...
function getTableInfo($inTableName, $inColumnName) { ....}
在内部我检查我设置的数组,以确保只有“祝福”表的表和列可访问:
$allowed_tables_array = array('tblTheTable');$allowed_columns_array['tblTheTable'] = array('the_col_to_check');
然后在运行PDO之前的PHP检查看起来像......
if(in_array($inTableName, $allowed_tables_array) && in_array($inColumnName,$allowed_columns_array[$inTableName])){ $sql = "SELECT $inColumnName AS columnInfo FROM $inTableName"; $stmt = $pdo->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC);}
![?](http://img1.sycdn.imooc.com/533e4c1500010baf02200220-100-100.jpg)
TA贡献1735条经验 获得超5个赞
使用前者本身并不比后者更安全,您需要清理输入,无论它是参数数组还是简单变量的一部分。所以我认为使用后一种形式没有任何问题$table
,只要你确保$table
在使用之前内容是安全的(alphanum加上下划线?)。
- 4 回答
- 0 关注
- 598 浏览
添加回答
举报