我想在PHP中创建一个联系人表单搜索。
示例条目:
名称:粉红色
电话:555-888-1234
我想在输入框中搜索姓名和电话,并返回LIKE匹配结果,不区分大小写。
例子:
在姓名中搜索'p'而不包含电话号码,并返回结果
在电话号码字段中搜索'5',没有名字,得到结果。
搜索"x"在name字段中,没有得到结果,目前我得到了结果。
$query = "SELECT * FROM contacts WHERE name ~* '.*$name.*' OR phone ~* '.*$phone.*'";
想象一下(但不要实际运行它!)如果在name字段中放入以下内容会发生什么:
');DROP TABLE contacts;--
欢迎学习SQL注入。Bye Bye contacts表,除非您使用的用户不是表的所有者——但即使这样,DELETE FROM contacts;
也可能工作。
猜一下,发生的事情是,如果phone
或name
是空白的,则将其替换为空字符串。所以给定.*$phone.*
,产生一个像.*.*
的正则表达式,当然是匹配任何。因为有一个OR
子句,您的测试与空白电话和名称= x
测试
name ~* '.*x.*' OR phone ~* '.*.*'
当然对于name
中的任何值都是正确的。
您应该能够通过查看实际运行的查询来判断这一点。打开postgresql.conf
中的log_statement=all
,使用PostgreSQL查询日志
你需要做的是:
动态构建查询。如果过滤器中没有
phone
的条目,则完全去掉OR phone ~* ...
子句。使用查询参数将您的值正确地注入到查询中。即使您是通过在客户端进行连接或使用如下方式来连接值,也可以这样做:
WHERE name ~* '.*'||$1||'.*'
其中
$1
是查询参数占位符。我不记得PHP是否使用?
之类的;在将值作为参数发送之前,转义正则表达式元字符。否则,用
(
搜索phone
将产生语法错误,因为无效的regexp。