似乎该主题上的每个问题都是mysqli预准备语句和PHP中直接mysqli查询之间的区别,但是当预准备语句不能满足您的需求时该怎么办。
在执行简单查询时,准备好的语句无疑是解决问题的方法:
$stmt = $connection->prepare("SELECT * FROM my_table WHERE id = ?");
但是,当事情变得更加复杂时呢?从PHP手册中:
但是,在选择列表(用于命名要由SELECT语句返回的列)或指定二进制运算符的两个操作数(例如=等号)的选择列表中,不允许使用[markers]作为标识符(例如表或列名) 。
对于确实需要指定二进制运算符的两个操作数或具有其他一些限制的复杂查询,这将成为一个问题mysqli_prepare
。
就我而言,我需要执行一些查询以返回博客条目的结果(这是一个简化的示例,我的连接变量实际上是博客类的私有属性,但是您可以理解):
$query = $connection->query("SELECT * FROM my_table WHERE $field = '$search'");
在此示例中,$field
变量是要搜索的列,$search
变量是要搜索的列。对于准备好的语句,这种类型的查询是不可能的。
我已经对诸如此类的功能进行了很多周密的计划,并且由于我知道只有X个列可供搜索,因此我使用条件语句来检查$field
是否等于这些列之一,并mysqli_real_escape_string
避免任何可能的情况发生。引用字符。但是,这是好习惯吗?基于我在SO上的阅读和回答,您应该始终使用准备好的语句,但是在这些示例中我从未见过复杂的查询。是否有防止SQL注入的更好方法,使用预处理语句的更高级方法,还是我应该在这里坚持非常仔细的验证?
是和否:有必要再次检查该$field
变量的白名单-这是防止sql注入的唯一方法-但mysqli_real_escape_string
在该$field
变量上使用毫无意义。如果您的列名是保留字或以数字开头,则应在反引号中将其引号,但仅此而已。
您仍然应该对$search
变量使用准备好的语句,尽管这里mysqli_real_escape_string
也可以这样做(而不是准备好的语句,不能同时使用两者)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句