Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用准备好的PDO语句按参数设置订单?_Php_Mysql_Pdo - Fatal编程技术网

Php 如何使用准备好的PDO语句按参数设置订单?

Php 如何使用准备好的PDO语句按参数设置订单?,php,mysql,pdo,Php,Mysql,Pdo,在SQL的ORDER BY部分中使用参数时遇到问题。它不会发出任何警告,但不会打印任何内容 $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_ST

在SQL的ORDER BY部分中使用参数时遇到问题。它不会发出任何警告,但不会打印任何内容

$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常量或其他等效值


谢谢

我认为你不能:

在order by子句中使用占位符 绑定列名:您只能绑定值或变量,并将它们的值注入到准备好的语句中。
是的,您无法将其直接插入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";
方向也一样

我编写了一个在这种情况下使用的示例,它大大减少了需要编写的代码量:

$order = white_list($order, ["name","price","qty"], "Invalid field name");
$direction = white_list($direction, ["ASC","DESC"], "Invalid ORDER BY direction");

$sql = "SELECT field from table WHERE column = ? ORDER BY $order $direction";
$stmt = $db->prepare($sql);
$stmt->execute([$is_live]);

这里的想法是检查该值,如果该值不正确,则会引发错误

如果我没有完全错的话,帕斯卡是对的。 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的正确转义,但是由于您是手动设置的,而不是通过用户输入设置的,所以我认为您已经全部设置好了。

我认为您不能将ASC/DESC作为预准备语句的一部分,但是如果您在sql查询中这样列出它们,则可以将它们列:

// Validate between 2 possible values:
$sortDir = isset($_GET['sortDir']) && $_GET['sortDir'] === 'ASC' ? 'ASC' : 'DESC';
$sql = "
...
     order 
        by 
           case :orderByCol
               when 'email' then email
               when 'age' then age
               else surname
           end
           $sortDir
";
$stmt = $db->prepare($sql);
$stmt->bindParam(':orderByCol', $someColumn);
$stmt->execute();
由于ASC/DESC只有两个可能的值,因此可以使用php代码轻松地验证并选择它们作为硬编码值


您也可以为此使用ELTFIELD、、、、、、、、函数,但排序将始终作为字符串进行,即使列是一种数字数据类型,应使用数字语义/排序规则进行排序。

不幸的是,我猜您无法使用准备好的语句进行排序。 由于不同的列可能具有可以使用特殊排序策略排序的值,因此它将不可缓存

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

在ORDER by子句中可以使用准备好的语句,不幸的是,您需要传递列的顺序而不是名称,并且需要使用类型设置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();
这是可能的。在“order by”子句中,可以使用数字而不是字段名。这是一个从1开始的数字,按照查询中字段名称的顺序排列。您可以将ASC或DESC的字符串串联在一起 从tab1 order by中选择col1、col2、col3?+strDesc+限值10,5。
strDesc=ASC/DESC.

如果他不打算更改orderby列和方向,那么我认为将它们作为变量毫无意义。老实说,可以按子句的顺序绑定值而不是标识符。这部分是正确的。只能使用绑定占位符提供值。永远不可能使用绑定占位符来提供标识符,如表名、列名、SQL关键字或SQL语法中除值以外的任何其他部分。基本上,绑定占位符可以代替字符串文字、日期文字或数字文字。时期但正如zerkms所指出的,由于可以在ORDER BY子句中使用文字作为表达式的一部分,实际上可以在ORDER BY子句中使用绑定占位符作为表达式的一部分;对于字符串,您只需在数组$input、$valid\U orderbys\U数组中检查它是否应该基本上执行相同的操作。聪明的解决方法。但就我个人而言,我认为首先必须计算列号太多了。$direction仍然存在一个问题,您刚刚硬编码为DESC。