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

PHP实现密钥与支付状态双条件校验时SQL查询报非对象错误

联合校验逻辑报错的原因与调整方案

原代码的核心问题

  • 最直接的报错根源:因为PHP运算符优先级规则,写在同一行的$result = $conn->query($sql) && $result1 = $conn->query($eql); 执行逻辑完全偏离预期。&&的运算优先级远高于赋值号=,这行代码实际等价于把整个逻辑与判断的布尔结果(true/false)赋值给$result,$result根本没有拿到数据库查询返回的结果集对象。后续代码试图读取$result->num_rows时,操作的是布尔值而非对象,自然触发“在非对象上获取属性”的报错。
  • 支付状态校验逻辑完全脱钩:原支付查询SELECT payment FROM new_keys WHERE payment =1 是统计全表所有已支付的记录,没有把支付状态和当前用户输入的密钥做绑定。哪怕任意一个无关用户的密钥处于已支付状态,校验都会通过,完全不符合“对应用户输入的密钥本身已支付”的业务要求。
  • 校验条件逻辑错误:判断支付状态的条件写的num_rows > 1不符合约定,只要对应当前密钥存在1条已支付的记录就满足要求,大于1的判断逻辑会出现单条已支付记录被漏判的问题。
  • 缺失结果合法性校验:没有判断数据库查询是否成功返回了合法的结果集对象,一旦查询执行报错返回false,直接读取结果属性就会触发非对象类报错。

可运行的调整方案

调整原则

  • 每个数据库查询单独执行、单独赋值,绝不把查询赋值和逻辑判断写在同一行
  • 查询支付状态时必须绑定当前用户输入的密钥,不做全表无关联扫描
  • 读取结果属性前先校验结果是否为合法的结果集对象
  • 校验条件匹配业务约定:存在1条匹配的有效记录即通过校验

方案1:payment字段与密钥存储在同一张表(推荐,性能最优)

如果原来存software_key、decrypt_key的表本身就有payment字段,不需要拆分两个查询,直接把校验条件拼接在单条SQL里即可:

// 单条SQL同时匹配密钥有效、已支付两个条件
$sql = "SELECT decrypt_key FROM keys 
        WHERE software_key = '" . $software_key_encoded . "' 
        AND payment = 1";
$result = $conn->query($sql);

// 先校验查询返回合法结果集,再判断是否有匹配记录
if ($result && $result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo $row["decrypt_key"];
    }
} else {
    echo "Failed";
}
$conn->close();

方案2:payment字段存储在独立的new_keys表,通过software_key关联

如果支付状态确实存在独立的数据表,必须给支付查询加上当前密钥的关联条件,分开执行两个查询:

// 原有密钥校验查询,单独执行赋值
$sql = "SELECT decrypt_key FROM keys WHERE software_key='" . $software_key_encoded . "'";
$result = $conn->query($sql);

// 支付状态查询,必须绑定当前输入的密钥,筛选已支付的记录
$eql = "SELECT payment FROM new_keys 
        WHERE software_key = '" . $software_key_encoded . "' 
        AND payment = 1";
$result1 = $conn->query($eql);

// 同时校验两个结果集合法、都有匹配的有效记录
if ($result instanceof mysqli_result 
    && $result->num_rows > 0 
    && $result1 instanceof mysqli_result 
    && $result1->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo $row["decrypt_key"];
    }
} else {
    echo "Failed";
}
$conn->close();

额外安全提示:现有代码直接将$software_key_encoded拼接到SQL字符串中存在SQL注入风险,长期使用建议替换为预处理语句的绑定参数写法,该优化不影响当前功能的正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 18:45:03