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

MySQL查询返回null问题排查及数据提取至数组方法咨询

问题排查与修复方案

先给你梳理几个核心问题,这些都是导致你返回null和功能异常的关键:

1. 缺少错误检测,根本不知道哪里出错

mysqli_query执行失败时会返回false而非null,但你没做任何错误检查,连数据库连接是否成功都没验证。先加上这些调试代码,能直接定位问题:

// 先检查数据库连接是否成功
$con= mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_DATA);
if (!$con) {
    die(json_encode(['error' => '数据库连接失败: ' . mysqli_connect_error()]));
}

// 执行查询后检查错误
$result = mysqli_query($con,$query);
if (!$result) {
    die(json_encode(['error' => '查询失败: ' . mysqli_error($con)]));
}

加上这些后,你就能直接看到是SQL语法错误,还是参数格式有问题。

2. 致命问题:$n_quakes只是SQL字符串,从未执行查询

你定义了计数的SQL语句,但完全没调用mysqli_query去执行它,最后直接把字符串传给json_encode,这完全不对。要拿到计数结果,得执行查询并取出数值:

// 执行计数查询
$count_result = mysqli_query($con, $n_quakes);
if (!$count_result) {
    die(json_encode(['error' => '计数查询失败: ' . mysqli_error($con)]));
}
// 取出COUNT(*)的结果
$count_row = mysqli_fetch_row($count_result);
$total_quakes = $count_row[0];
mysqli_free_result($count_result);

3. 严重安全问题:直接拼接GET参数导致SQL注入,还可能引发语法错误

你直接把$_GET的参数拼进SQL里,这不仅会被SQL注入攻击,还可能因为参数格式(比如带特殊字符、空值)导致SQL语法错误。必须用预处理语句来处理:
举个替换查询部分的例子:

// 以带地理条件的查询为例,用预处理
if(isset($_GET['lat-sup'])) {
    $query = "SELECT * FROM earthquakes 
              WHERE milliseconds BETWEEN ? AND ? 
                AND magnitude BETWEEN ? AND ? 
                AND ipocentro BETWEEN ? AND ? 
                AND latitude BETWEEN ? AND ? 
                AND longitude BETWEEN ? AND ? 
              OFFSET ? LIMIT 400";
    $stmt = mysqli_prepare($con, $query);
    // 绑定参数,"iddddddidd"表示对应参数的类型(i=int, d=float),根据你的字段类型调整
    mysqli_stmt_bind_param($stmt, "iddddddidd", $ieri, $oggi, $magn_min, $magn_max, $ipo_min, $ipo_max, $lat_inf, $lat_sup, $lng_sin, $lng_des, $offset);
} else {
    // 不带地理条件的预处理语句
    $query = "SELECT * FROM earthquakes 
              WHERE milliseconds BETWEEN ? AND ? 
                AND magnitude BETWEEN ? AND ? 
                AND ipocentro BETWEEN ? AND ? 
              OFFSET ? LIMIT 400";
    $stmt = mysqli_prepare($con, $query);
    mysqli_stmt_bind_param($stmt, "idddddd", $ieri, $oggi, $magn_min, $magn_max, $ipo_min, $ipo_max, $offset);
}
// 执行预处理语句
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

预处理语句会自动处理参数的格式和转义,彻底避免注入和语法错误。

4. mysqli_free_result的使用错误

你传了$array_quakes给mysqli_free_result,但这个函数需要的是查询结果集(也就是$result或者$count_result),不是你自己组装的数组。正确的用法是:

mysqli_free_result($result);
// 如果你用了预处理,还要关闭语句
mysqli_stmt_close($stmt);

5. json_encode的参数错误

json_encode只接受一个参数,你传了两个($n_quakes和$array_quakes),这会导致只编码第一个参数。应该把计数和地震数据放到一个数组里再编码:

// 先初始化数组,避免无结果时报错
$array_quakes = [];
while ($row = mysqli_fetch_assoc($result)) {
    $array_quakes[] = $row;
}

// 组合成一个关联数组再编码
echo json_encode([
    'total' => $total_quakes,
    'quakes' => $array_quakes
]);

6. 变量类型的小问题

你把所有$_GET参数转成字符串,但如果这些字段是数字类型(比如milliseconds、magnitude),直接转成整数/浮点型更合适,避免预处理时的类型混淆:

$ieri = (int)$_GET['ieri'];
$oggi = (int)$_GET['oggi'];
$magn_min = (float)$_GET['magn-min'];
$magn_max = (float)$_GET['magn-max'];
// 其他参数同理,根据字段类型转换

完整修正后的核心代码片段

include_once("../config.php");
$con= mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_DATA);
if (!$con) {
    die(json_encode(['error' => '数据库连接失败: ' . mysqli_connect_error()]));
}

// 转换参数类型
$ieri = (int)$_GET['ieri'];
$oggi = (int)$_GET['oggi'];
$magn_min = (float)$_GET['magn-min'];
$magn_max = (float)$_GET['magn-max'];
$ipo_min = (float)$_GET['ipo-min'];
$ipo_max = (float)$_GET['ipo-max'];
$offset = (int)(($_GET['id-call'] - 1)*400);

// 处理查询
if(isset($_GET['lat-sup'])) {
    $lat_sup = (float)$_GET['lat-sup'];
    $lat_inf = (float)$_GET['lat-inf'];
    $lng_sin = (float)$_GET['lng-sin'];
    $lng_des = (float)$_GET['lng-des'];
    
    // 数据查询
    $query = "SELECT * FROM earthquakes 
              WHERE milliseconds BETWEEN ? AND ? 
                AND magnitude BETWEEN ? AND ? 
                AND ipocentro BETWEEN ? AND ? 
                AND latitude BETWEEN ? AND ? 
                AND longitude BETWEEN ? AND ? 
              OFFSET ? LIMIT 400";
    $stmt = mysqli_prepare($con, $query);
    mysqli_stmt_bind_param($stmt, "iddddddidd", $ieri, $oggi, $magn_min, $magn_max, $ipo_min, $ipo_max, $lat_inf, $lat_sup, $lng_sin, $lng_des, $offset);
    
    // 计数查询
    $count_query = "SELECT COUNT(*) FROM earthquakes 
                    WHERE milliseconds BETWEEN ? AND ? 
                      AND magnitude BETWEEN ? AND ? 
                      AND ipocentro BETWEEN ? AND ? 
                      AND latitude BETWEEN ? AND ? 
                      AND longitude BETWEEN ? AND ?";
    $count_stmt = mysqli_prepare($con, $count_query);
    mysqli_stmt_bind_param($count_stmt, "iddddddidd", $ieri, $oggi, $magn_min, $magn_max, $ipo_min, $ipo_max, $lat_inf, $lat_sup, $lng_sin, $lng_des);
} else {
    // 数据查询
    $query = "SELECT * FROM earthquakes 
              WHERE milliseconds BETWEEN ? AND ? 
                AND magnitude BETWEEN ? AND ? 
                AND ipocentro BETWEEN ? AND ? 
              OFFSET ? LIMIT 400";
    $stmt = mysqli_prepare($con, $query);
    mysqli_stmt_bind_param($stmt, "idddddd", $ieri, $oggi, $magn_min, $magn_max, $ipo_min, $ipo_max, $offset);
    
    // 计数查询
    $count_query = "SELECT COUNT(*) FROM earthquakes 
                    WHERE milliseconds BETWEEN ? AND ? 
                      AND magnitude BETWEEN ? AND ? 
                      AND ipocentro BETWEEN ? AND ?";
    $count_stmt = mysqli_prepare($con, $count_query);
    mysqli_stmt_bind_param($count_stmt, "iddddd", $ieri, $oggi, $magn_min, $magn_max, $ipo_min, $ipo_max);
}

// 执行计数查询
mysqli_stmt_execute($count_stmt);
$count_result = mysqli_stmt_get_result($count_stmt);
$count_row = mysqli_fetch_row($count_result);
$total_quakes = $count_row[0];
mysqli_free_result($count_result);
mysqli_stmt_close($count_stmt);

// 执行数据查询
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$array_quakes = [];
while ($row = mysqli_fetch_assoc($result)) {
    $array_quakes[] = $row;
}
mysqli_free_result($result);
mysqli_stmt_close($stmt);

// 返回JSON
echo json_encode([
    'total' => $total_quakes,
    'quakes' => $array_quakes
]);

mysqli_close($con);

先按照上面的步骤加错误检测,应该能马上找到最初的问题(比如SQL语法错了),然后逐步替换成预处理语句,就能彻底解决null的问题,同时让代码更安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:07:57