如何使用准备好的PDO语句设置ORDER BY params?

我在我的SQL的ORDER BY部分中使用PARAMS有问题。 它不会发出任何警告,但不会打印任何内容。

 $order = 'columnName'; $direction = 'ASC'; $stmt = $db->prepare("SELECT field from table WHERE column = :my_param ORDER BY :order :direction"); $stmt->bindParam(':my_param', $is_live, PDO::PARAM_STR); $stmt->bindParam(':order', $order, PDO::PARAM_STR); $stmt->bindParam(':direction', $direction, PDO::PARAM_STR); $stmt->execute(); 

:my_param工作,但不是:order:direction 。 它没有正确的内部转义吗? 我坚持插入它直接在SQL? 像这样:

 $order = 'columnName'; $direction = 'ASC'; $stmt = $db->prepare("SELECT * from table WHERE column = :my_param ORDER BY $order $direction"); 

有一个PDO::PARAM_COLUMN_NAME常量或一些等价的?

谢谢!

这里来的问题表明,广泛爱预准备的声明是不是银弹,嘿嘿:)

是的,当然,你被困在SQL中直接插入它有一些预防措施。 每个操作符/标识符都必须在脚本中进行硬编码 ,如下所示:

 $orders=array("name","price","qty"); $key=array_search($_GET['sort'],$orders); $order=$orders[$key]; $query="SELECT * from table WHERE is_live = :is_live ORDER BY $order"; 

方向相同。

请注意,bindParam不会转义,因为根本不需要转义。 它绑定。

我不认为你可以:

  • order by使用占位符
  • 绑定列名称:只能绑定值或variables,并将其值写入准备好的语句中。

有可能ORDER BY子句中使用PDO_PARAM_INT准备语句,不幸的是,您需要传递名称PDO_PARAM_INT的列的顺序,并且需要设置types为PDO_PARAM_INT

在MySQL中,您可以使用此查询获取列的顺序:

 SELECT column_name, ordinal_position FROM information_schema.columns WHERE table_name = 'table' and table_schema = 'database' 

PHP代码:

 $order = 2; $stmt = $db->prepare("SELECT field from table WHERE column = :param ORDER BY :order DESC"); $stmt->bindParam(':param', $is_live, PDO::PARAM_STR); $stmt->bindParam(':order', $order, PDO::PARAM_INT); $stmt->execute(); 

我不认为你可以把ASC / DESC作为准备好的声明的一部分,但你可以列。

  order by case :order when 'colFoo' then colFoo when 'colBar' then colBar else colDefault end $direction 

由于ASC / DESC只有两个可能的值,因此您可以轻松validation并select它们作为硬编码值。

你也可以使用ELT(FIELD(,,,,,),,,,,)函数来完成这个任务,但是总是以一个string的forms进行sorting,即使它是一个数字列。

不幸的是,我猜你不能用预先准备的陈述来做。 这将使它不可caching,因为不同的列可能具有可以使用特殊sorting策略进行sorting的值。

使用标准转义创build查询并直接执行。

这是可能的 。 您可以在'order by'子句中使用数字而不是字段名称。 这是一个从1开始的数字,并且按查询中字段名称的顺序排列。 你可以连接一个string为ASC或DESC。 例如“从tab1按顺序selectcol1,col2,col3?”+ strDesc +“limit 10,5”。 strDesc =“ASC”/“DESC”。

如果我不完全错误,帕斯卡是正确的。
在PDO中唯一可能的绑定是绑定的值,就像你使用':my_param'参数一样。
但是,在以下方面没有造成任何伤害:

 $stmt = $db->prepare("SELECT field from table WHERE column = :my_param ORDER BY ".$order ." ".$direction); $stmt->bindParam(':my_param', $is_live, PDO::PARAM_STR); $stmt->execute(); 

唯一需要注意的是$order$direction的正确转义,但是由于你手动设置了它们,并没有通过用户input来设置它们,所以我认为你已经设定好了。

创build一个if-else条件。
如果(ascCondion)然后绑定值,但硬编码ORDER BY columnName ASC
其他
绑定值,但硬编码ORDER BY COlumnName DESC