使用 mysqli prepare with ORDER BY 的问题
Issues using mysqli prepare with ORDER BY
我正在努力更新网站以避免任何 MySQL 注入攻击的机会。这导致我将 mysqli 与 Php.
一起使用
我现在尝试在网站上执行搜索时遇到此错误:
Fatal error: Call to a member function bind_param() on a non-object in ...
搜索旨在从文本框中获取用户输入并在数据库中搜索包含用户输入的特定字符串的记录。我尝试运行的代码如下:
$sql = "SELECT * FROM periodicals WHERE MATCH(author, title, type, keyword, citation) AGAINST (? IN BOOLEAN MODE) ORDER BY ? ? LIMIT ?,?";
$stmt = $conn -> prepare($sql);
$stmt -> bind_param("sssii", $param1, $param2, $param3, $param4, param5);
$param1 = $trimmed; //contains a keyword entered by user to search for
$param2 = $column; // contains which column to sort by (selected by user)
$param3 = $sort; // contains 'ASC' or 'DESC' for sorting (selected by user)
$param4 = (empty($s)) ? 0 : $s; //contains offset for LIMIT
$param5 = $limit; // contains number of values to retrieve
我使用了var_dmup($stmt)
,它返回了false,这意味着对prepare()
的调用没有成功。
我读到不正确的 sql 查询可能会导致此错误,并通过 运行 对 sql 进行检查以确保查询正常工作(使用值而不是?' s) 直接在数据库上,没有遇到任何错误或警告。
然后我做了一些实验。我想我将问题缩小到 SQL 查询的 ORDER BY ? ?
部分,因为代码将 运行 并在第二个 ?
更改为 ASC
or DESC
和 bind_param()
调整匹配如下:
$sql = "SELECT * FROM periodicals WHERE MATCH(author, title, type, keyword, citation) AGAINST (? IN BOOLEAN MODE) ORDER BY ? DESC LIMIT ?,?";
$stmt = $conn -> prepare($sql);
$stmt -> bind_param("ssii", $param1, $param2, $param4, param5);
$param3
的值在代码前面设置为 DESC
或 ASC
。在编写将值存储到 $sort
的代码时,我在测试中使用 var_dump()
来确保这一点,因此我不认为它向查询提供了不正确的值。
如果有人对我如何解决这个问题或出了什么问题有任何建议,我将不胜感激。
order by
的参数之间需要一个逗号。所以,如果你有两把钥匙,你会这样做:
ORDER BY ?, ?
但是您希望第二个是 ASC
或 DESC
。您不能将它们作为参数直接传递。您可以将它们构建到字符串中,这应该是安全的,因为您只会根据 php 中的逻辑放入 ASC
或 DESC
。或者,您可以传入一个字符串并执行:
ORDER BY (CASE WHEN ? = 'DESC' THEN ? END) DESC,
? ASC
当第一个表达式的计算结果为真时,您将使用该值。否则,所有值都是 NULL
-- 并且第二个子句生效。
bind_param
是用来防止SQL Injection
的,大家知道的。它通过确保您只能输入值而不能更改实际的 SQL
语句来做到这一点。
如果您尝试输入 ASC
或 DESC
作为参数,您会发现它无法完成。仅仅是因为这意味着您正在更改 SQL
语句。
您应该自己检查值并在查询中输入它。
<?php
$ascOrDesc = ($uservalue=="DESC") ? "DESC" : "ASC";
$sql = "SELECT * FROM periodicals WHERE MATCH(author, title, type, keyword, citation) AGAINST (? IN BOOLEAN MODE) ORDER BY ? " . $ascOrDesc;
?>
请记住,如果您使用 ?
作为 ORDER BY
class 中的列名称,您实际上并未按该列值排序。
如果您输入 Name
作为列,您将按值 'name' 而不是列 name
对所有行进行排序。所以根本没有排序,因为每一行都与相同的值匹配。
我正在努力更新网站以避免任何 MySQL 注入攻击的机会。这导致我将 mysqli 与 Php.
一起使用我现在尝试在网站上执行搜索时遇到此错误:
Fatal error: Call to a member function bind_param() on a non-object in ...
搜索旨在从文本框中获取用户输入并在数据库中搜索包含用户输入的特定字符串的记录。我尝试运行的代码如下:
$sql = "SELECT * FROM periodicals WHERE MATCH(author, title, type, keyword, citation) AGAINST (? IN BOOLEAN MODE) ORDER BY ? ? LIMIT ?,?";
$stmt = $conn -> prepare($sql);
$stmt -> bind_param("sssii", $param1, $param2, $param3, $param4, param5);
$param1 = $trimmed; //contains a keyword entered by user to search for
$param2 = $column; // contains which column to sort by (selected by user)
$param3 = $sort; // contains 'ASC' or 'DESC' for sorting (selected by user)
$param4 = (empty($s)) ? 0 : $s; //contains offset for LIMIT
$param5 = $limit; // contains number of values to retrieve
我使用了var_dmup($stmt)
,它返回了false,这意味着对prepare()
的调用没有成功。
我读到不正确的 sql 查询可能会导致此错误,并通过 运行 对 sql 进行检查以确保查询正常工作(使用值而不是?' s) 直接在数据库上,没有遇到任何错误或警告。
然后我做了一些实验。我想我将问题缩小到 SQL 查询的 ORDER BY ? ?
部分,因为代码将 运行 并在第二个 ?
更改为 ASC
or DESC
和 bind_param()
调整匹配如下:
$sql = "SELECT * FROM periodicals WHERE MATCH(author, title, type, keyword, citation) AGAINST (? IN BOOLEAN MODE) ORDER BY ? DESC LIMIT ?,?";
$stmt = $conn -> prepare($sql);
$stmt -> bind_param("ssii", $param1, $param2, $param4, param5);
$param3
的值在代码前面设置为 DESC
或 ASC
。在编写将值存储到 $sort
的代码时,我在测试中使用 var_dump()
来确保这一点,因此我不认为它向查询提供了不正确的值。
如果有人对我如何解决这个问题或出了什么问题有任何建议,我将不胜感激。
order by
的参数之间需要一个逗号。所以,如果你有两把钥匙,你会这样做:
ORDER BY ?, ?
但是您希望第二个是 ASC
或 DESC
。您不能将它们作为参数直接传递。您可以将它们构建到字符串中,这应该是安全的,因为您只会根据 php 中的逻辑放入 ASC
或 DESC
。或者,您可以传入一个字符串并执行:
ORDER BY (CASE WHEN ? = 'DESC' THEN ? END) DESC,
? ASC
当第一个表达式的计算结果为真时,您将使用该值。否则,所有值都是 NULL
-- 并且第二个子句生效。
bind_param
是用来防止SQL Injection
的,大家知道的。它通过确保您只能输入值而不能更改实际的 SQL
语句来做到这一点。
如果您尝试输入 ASC
或 DESC
作为参数,您会发现它无法完成。仅仅是因为这意味着您正在更改 SQL
语句。
您应该自己检查值并在查询中输入它。
<?php
$ascOrDesc = ($uservalue=="DESC") ? "DESC" : "ASC";
$sql = "SELECT * FROM periodicals WHERE MATCH(author, title, type, keyword, citation) AGAINST (? IN BOOLEAN MODE) ORDER BY ? " . $ascOrDesc;
?>
请记住,如果您使用 ?
作为 ORDER BY
class 中的列名称,您实际上并未按该列值排序。
如果您输入 Name
作为列,您将按值 'name' 而不是列 name
对所有行进行排序。所以根本没有排序,因为每一行都与相同的值匹配。