我在分析一些代码,发现了这个,
$sql = 'SELECT page.*, author.name AS author, updator.name AS updator '
. 'FROM '.TABLE_PREFIX.'page AS page '
. 'LEFT JOIN '.TABLE_PREFIX.'user AS author ON author.id = page.created_by_id '
. 'LEFT JOIN '.TABLE_PREFIX.'user AS updator ON updator.id = page.updated_by_id '
. 'WHERE slug = ? AND parent_id = ? AND (status_id='.Page::STATUS_REVIEWED.' OR status_id='.Page::STATUS_PUBLISHED.' OR status_id='.Page::STATUS_HIDDEN.')';
我在想“?”在where语句中的作用。它是某种参数保持器吗?
4条答案
按热度按时间cgh8pdjw1#
prepared语句在mysql中使用“?”来允许将参数绑定到语句。如果使用得当,被认为对sql注入更安全。这还允许更快的sql查询,因为请求只需编译一次,就可以重用。
g6ll5ycj2#
这些都是事先准备好的陈述,事先准备好的陈述有两大好处:
查询只需要解析(或准备)一次,但可以使用相同或不同的参数执行多次。准备好查询后,数据库将分析、编译并优化执行查询的计划。对于复杂的查询,此过程可能会占用足够的时间,如果需要使用不同的参数多次重复同一查询,则会显著降低应用程序的速度。通过使用准备好的语句,应用程序避免了重复分析/编译/优化循环。这意味着准备好的语句使用更少的资源,因此运行得更快。
准备语句的参数不需要引用;驱动程序会自动处理这个问题。如果应用程序专门使用准备好的语句,那么开发人员可以确保不会发生sql注入(但是,如果查询的其他部分是使用非scaped输入构建的,那么sql注入仍然是可能的)。
http://php.net/manual/en/pdo.prepared-statements.php
iezvtpos3#
?
在mysql中没有特殊意义WHERE =
声明,仅在准备好的声明中我们看到的最常见的情况是由于赋予
?
通过一些web框架,比如php和rails。?
只是语法错误:因为它没有被引用,而且在:
它返回:
显然没有特别的意义。
MySQL5.0准备语句
mysql 5.0增加了prepared statement特性,其语义与web框架中的问号类似。
文档示例:
输出:
这些字符也按预期转义特殊字符:
输出:
rails示例
例如,在rails中,问号被库的编程语言(ruby)的一个变量给出的参数所取代,例如:
它会自动引用参数以避免bug和sql注入,生成如下语句:
如果出现以下情况,报价将拯救我们:
8cdiaqws4#
问号表示稍后将被替换的参数。使用参数化查询比将参数直接嵌入查询更安全。
SQLServer调用这个参数化查询,oracle调用它绑定变量。
用法因执行查询所用的语言而异。
下面是一个如何从php使用它的示例。
假设
$mysqli
是数据库连接和people
是一个有4列的表。这个
'sssd'
是标识其余参数的标志,其中s
表示字符串和d
表示数字。