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

PHP执行MySQL查询定义变量时出现意外变量语法错误

问题原因
  • mysqli::query() 默认不支持单次执行多条SQL语句,你把多组SET、SELECT语句拼接在同一个字符串中调用该方法,会直接返回布尔值false,后续调用num_rows方法时就会抛出「在布尔值上调用成员函数」的致命错误。
  • SQL语句中日期属于字符串类型,直接拼接PHP变量未加单引号包裹,会触发SQL语法错误;同时未做参数转义,存在SQL注入风险。
  • 最终返回的聚合统计结果只有total_fl_built/total_qc_built/percentage三个字段,原代码循环读取date/hour/pnp_kdt等不存在的字段,会抛出未定义数组键的警告。
  • PHP语法错误:$total变量赋值的SQL字符串结尾没有添加语句结束分号;,会直接触发PHP解析错误。
  • 逻辑漏洞:未做除零判断,当统计的总装机量为0时,百分比计算会触发MySQL除以零错误;另外当前SQL是精确匹配开始、结束两个单日的数值,和你要做日期范围入参的需求不匹配。
修复方案

把多语句查询合并为单条聚合SQL,用预处理语句绑定参数规避注入和语法问题,补充参数校验、除零兜底逻辑,移除不存在的字段读取逻辑。

<?php
include 'action.php';

// 初始化并校验日期参数
$begindate = isset($_POST['start-date']) ? trim($_POST['start-date']) : '';
$enddate = isset($_POST['end-date']) ? trim($_POST['end-date']) : '';

// 按实际日期格式调整校验规则,这里默认是YYYY-MM-DD格式
if (empty($begindate) || empty($enddate) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $begindate) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $enddate)) {
    die("请提交合法的开始、结束日期");
}

// 单条SQL完成所有统计,用IFNULL做空值、除零兜底
// 如果你需要统计【整个日期范围内】的总装机、总质检量,把WHERE条件改为 `date` BETWEEN ? AND ? 即可
$sql = "SELECT 
    (SELECT IFNULL(SUM(`fl_built`), 0) FROM `records` WHERE `date` = ?) AS total_fl_built,
    (SELECT IFNULL(SUM(`fl_qc`), 0) FROM `records` WHERE `date` = ?) AS total_qc_built,
    ROUND(
        (SELECT IFNULL(SUM(`fl_qc`), 0) FROM `records` WHERE `date` = ?) / 
        (SELECT IFNULL(SUM(`fl_built`), 1) FROM `records` WHERE `date` = ?) * 100
    ) AS percentage
";

// 预处理绑定参数,彻底避免引号、注入问题
$stmt = $conn->prepare($sql);
// 按SQL中占位符顺序绑定4个字符串类型参数,若改成范围查询需同步调整参数顺序
$stmt->bind_param("ssss", $begindate, $enddate, $enddate, $begindate);
$stmt->execute();
$result = $stmt->get_result();

echo "<table border='1' cellpadding='8'>";
echo "<tr><th>总装机量</th><th>总质检量</th><th>完成率(%)</th></tr>";
if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "<tr>";
        echo "<td>{$row['total_fl_built']}</td>";
        echo "<td>{$row['total_qc_built']}</td>";
        echo "<td>{$row['percentage']}</td>";
        echo "</tr>";
    }
}
echo "</table>";

$stmt->close();
$conn->close();
?>
注意事项
  • 不推荐使用multi_query()实现多语句执行,该方法需要手动逐个处理每个语句返回的结果集,代码冗余且SQL注入风险远高于预处理语句。
  • 如果你的日期字段是DATETIME类型带时分秒,做范围查询时需要补充时间边界条件,避免漏算结束日期的数据。
  • 代码中用IFNULL将无匹配数据时的统计值默认置为0,百分比计算时分母用1兜底,不会出现空值、除零报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:36:22