PHP、MySQL、HTML流程中&符号导致的数据库查询失效问题
问题:PHP/HTML/MySQL中&符号导致搜索失效
在PHP+HTML+MySQL的业务流程里,遇到了一个&符号引发的问题:当输入框输入“H&C”时,数据库检索不到对应记录,但输入“US”却能正常返回结果。
数据库创建语句
DROP DATABASE IF EXISTS testamp; CREATE DATABASE testamp; USE testamp; DROP TABLE IF EXISTS acronym; CREATE TABLE acronym( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, terminology VARCHAR(255) NOT NULL UNIQUE, acronym VARCHAR(255) NOT NULL, index (terminology), index (acronym) ); INSERT INTO acronym (terminology, acronym) values ( "United States", "US" ) ,( "Humanitarian and compassionate", "H&C" ) ;
可通过select * from acronym where acronym like 'h%c';验证数据库中存在“H&C”记录。
前端输入框代码
<input type="text" name="acronym" size="50" placeholder="Enter an acronym" autofocus onkeydown="if (event.keyCode == 13) { this.form.submit(); return false; }" >
PHP处理逻辑
输入 sanitize 函数
function test_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; }
通过POST获取输入时调用:$acronym = test_input($_POST["acronym"]);
数据库查询代码
$link = create_link() or die("create_link"); $stmt = $link->prepare( 'SELECT acronym, terminology FROM acronym WHERE acronym like ? ORDER BY acronym' ); $like_value="%$acronym%"; $stmt->bind_param("s", $like_value) or die("bind_param"); $stmt->execute() or die("execute"); $stmt->store_result(); echo "<p>num_rows: " .$stmt->num_rows .PHP_EOL;
问题原因
问题出在htmlspecialchars()函数上:这个函数的作用是把HTML特殊字符转义成实体,比如会把&转换成&。当你输入“H&C”时,经过这个函数处理后,$acronym的值变成了H&C,用这个值去数据库匹配,自然找不到原本存储的“H&C”记录。而“US”没有特殊字符,所以不受影响。
解决方案
htmlspecialchars()是用于将内容输出到HTML页面时防止XSS攻击的,不是用于数据库查询的输入处理。你需要调整处理逻辑:
- 修改
test_input函数,去掉htmlspecialchars():
function test_input($data) { $data = trim($data); $data = stripslashes($data); // 移除htmlspecialchars,数据库查询不需要HTML转义 return $data; }
- 如果你需要在页面上输出查询到的内容,在输出的时候再使用
htmlspecialchars()处理,比如:
// 假设从数据库取出的字段是$row['acronym'] echo htmlspecialchars($row['acronym']);
另外,你使用预处理语句(prepare+bind_param)的做法是正确的,这已经足够防止SQL注入,不需要额外的HTML转义来处理数据库查询的输入。
内容的提问来源于stack exchange,提问作者sofname
相关产品推荐
相关产品推荐

