2012-10-21 55 views
0

我有一个“ajax脚本/处理程序”,它返回一堆产品类别到我的jqGrid。在SQL最终看起来就像这样:PHP PDO问题与清理OR​​DER BY字段

$sql = 'SELECT * FROM product_categories ORDER BY :sidx :sord LIMIT :start , :limit'; 
$sth = $dbh->prepare($sql); 
$sth->bindParam(':sidx', $sidx); 
$sth->bindParam(':sord', $sord); 
$sth->bindParam(':start', $start, PDO::PARAM_INT); 
$sth->bindParam(':limit', $limit, PDO::PARAM_INT); 
$sth->execute(); 

现在,我已经与“$开始”的问题,因为PDO显然有一些问题与限制,使我不得不明确地将其设置为(INT),所以上述可以工作。我的下一个问题是ORDER BY字段被引用。我如何停止报价?我可以直接传递'$ sidx'和'$ sord'的值而不消毒它们,但这会很危险。 眼下,获取生成上面的SQL为:

SELECT * FROM product_categories ORDER BY 'product_category' 'asc' LIMIT 0 , 10 

当我真正需要它看起来像:

SELECT * FROM product_categories ORDER BY product_category asc LIMIT 0 , 10 
+0

您是否允许用户按列和方向输入自己的订单? –

+0

什么是$ sord –

+0

jqGrid发送上述脚本处理程序的列顺序字段和方向,例如:script.php?_search = false&nd = 1350834280848&rows = 10&page = 1&sidx = product_category&sord = desc将意味着脚本按照product_category字段顺序排列方向 – SupaMonkey

回答

1

也许最好的解决方案将直接通过$sidx$sord值不消毒它们,但之前已经过验证。如:

$sidx = (!in_array($sidx,array('name','slug','description'))) ? 'name' : $sidx; 
$sord = (!in_array($sord,array('asc','desc'))) ? 'asc' : $sord; 
$sql = 'SELECT * FROM product_categories ORDER BY '.$sidx.' '.$sord.' LIMIT :start , :limit'; 
$sth = $dbh->prepare($sql); 
$sth->bindParam(':start', $start, PDO::PARAM_INT); 
$sth->bindParam(':limit', $limit, PDO::PARAM_INT); 
$sth->execute(); 
+0

这可能是一个解决方案,是的,但是因为我在许多数据库表上使用了这个'代码模板';每次获得此设置将会花费更多的工作量。我不明白为什么不只是一个普通的mysql_real_escape_string类型的PDO功能!我开始希望我坚持MySQLi! – SupaMonkey

+1

'mysql_real_escape_string()'不用于这些目的。如果我通过'sidx'就像'name ASC; DROP TABLE product_categories;''mysql_real_escape_string()'不保护您的查询。如果你在控制结构中使用变量,你应该像上面那样检查它们。如果你会找到其他解决方案,请告诉我们 – Mikhail

+0

谢谢,我必须这样做,直到有更好的事情发生 - 如果它曾经做过:) – SupaMonkey