我正在尝试在PHP中创建联系表单搜索。
示例条目:
姓名:Pink
电话:555-888-1234
我想搜索名称和电话的输入框,并返回LIKE匹配结果不区分大小写。
示例:
在名称中搜索“p”,没有电话号码,然后取回结果。
在电话号码字段中搜索“5”并且没有名称,获得结果。
在名称字段中搜索“x”,没有结果,目前我得到了结果。
$query = "SELECT * FROM contacts WHERE name ~* '.*$name.*' OR phone ~* '.*$phone.*'";
答案 0 :(得分:2)
想象一下(但实际上并没有运行它!)如果你把它放在名字字段中会发生什么:
');DROP TABLE contacts;--
Welcome to SQL injection。再见联系表,除非你明智地与不是表所有者的用户一起运行 - 但即便如此DELETE FROM contacts;
也可能有效。
猜测一下,发生的事情是,如果空白字符串为phone
或name
,则将其替换为空字符串。因此,.*$phone.*
生成了像.*.*
这样的正则表达式,当然匹配任何。由于有OR
条款,您的测试使用空白电话和名称= x
测试
name ~* '.*x.*' OR phone ~* '.*.*'
对name
中的任何值都是如此。
您应该通过查看实际运行的查询来说明这一点。打开log_statement=all
中的postgresql.conf
并使用PostgreSQL查询日志。
您需要做的是:
动态构建查询。如果phone
的过滤条件中没有条目,请完全取消OR phone ~* ...
条款。
使用查询参数将值正确地注入查询中。即使你通过连接客户端或类似的东西来连接值,你也可以这样做:
WHERE name ~* '.*'||$1||'.*'
其中$1
是查询参数占位符。我不记得PHP是使用那个还是?
或其他什么;见文档。
在将值作为参数发送之前,先在值中转义正则表达式元字符。否则,使用phone
搜索(
会因正则表达式无效而产生语法错误。