You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中MySQL预处理语句出现伪随机语法错误求助

问题:MySQL预处理语句执行时出现随机语法错误,输入被当作代码解析?

我在PHP中用预处理语句实现了一个MySQL查询,目的是防止SQL注入。这个查询会扫描文章数据库,搜索$derired_word:词在标题中权重1000,摘要中100,仅在正文中10;通过两个JOIN获取额外信息,已经为MATCH()涉及的所有字段创建了FULLTEXT索引。

预处理语句代码如下:

$stmt = $conn->prepare(
    "SELECT a.articleTitle, a.articleSummary, a.articleText, a.articleText2, a.date, b.tags, b.icon, c.user

    MATCH (a.articleTitle) AGAINST ((?) IN BOOLEAN MODE) * 1000 AS rel1,
    MATCH (a.articleSummary) AGAINST ((?) IN BOOLEAN MODE) * 100 AS rel2,
    MATCH (a.articleText, a.articleText2) AGAINST ((?) IN BOOLEAN MODE) * 10 AS rel3

    FROM table_a a
    INNER JOIN table_b b ON (a.id = b.id)
    INNER JOIN table_c c ON a.id = c.id
    
    WHERE MATCH (articleTitle, articleSummary, articleText, articleText2) 
    
    AGAINST ((?) IN BOOLEAN MODE)
    
    ORDER BY (rel1)+(rel2)+(rel3) DESC
                
    LIMIT 10");

$stmt->bind_param("ssss", $derired_word, $derired_word, $derired_word, $derired_word);

执行时出现如下错误:

PHP Fatal error: Uncaught mysqli_sql_exception: syntax error, unexpected '+' in /var/www/html/a.php:7371

Stack trace:

#0 /var/www/html/a.php(7371): mysqli_stmt->execute()

#1 /var/www/html/a.php(9234): call()

#2 /var/www/html/call2.php(428): call3()

#3 {main}

thrown in /var/www/html/a.php on line 7371, referer: https://xxxxxx

奇怪的是报错里的意外字符每次调用都不一样(比如@、)、-、$end),看起来像是预处理语句没正常工作,输入数据被当作代码解析了,这是什么原因?


解决分析

这不是预处理语句的问题,核心是SQL语法错误:在SELECT字段列表中,最后一个常规字段c.user和后面的MATCH(...) AS rel1之间缺少逗号,导致SQL解析器无法正确识别字段边界,后续的内容被错误解析,加上每次$derired_word的内容不同,就会出现随机的“意外字符”报错。

修正后的代码只需在c.user后面添加逗号,另外可以去掉AGAINST里多余的括号((?)改成?不影响功能,更简洁):

$stmt = $conn->prepare(
    "SELECT a.articleTitle, a.articleSummary, a.articleText, a.articleText2, a.date, b.tags, b.icon, c.user,

    MATCH (a.articleTitle) AGAINST (? IN BOOLEAN MODE) * 1000 AS rel1,
    MATCH (a.articleSummary) AGAINST (? IN BOOLEAN MODE) * 100 AS rel2,
    MATCH (a.articleText, a.articleText2) AGAINST (? IN BOOLEAN MODE) * 10 AS rel3

    FROM table_a a
    INNER JOIN table_b b ON (a.id = b.id)
    INNER JOIN table_c c ON a.id = c.id
    
    WHERE MATCH (articleTitle, articleSummary, articleText, articleText2) 
    
    AGAINST (? IN BOOLEAN MODE)
    
    ORDER BY (rel1)+(rel2)+(rel3) DESC
                
    LIMIT 10");

$stmt->bind_param("ssss", $derired_word, $derired_word, $derired_word, $derired_word);

另外可以优化查询性能:当前代码重复调用了4次MATCH,可以通过子查询或表达式复用的方式减少重复计算,不过这属于性能优化范畴,优先解决语法错误即可。

内容的提问来源于stack exchange,提问作者carla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 02:51:23