CodeIgniter 3 查询未返回 null 或 0 的原因及正确写法

CodeIgniter 3 查询未返回 null 或 0 的原因及正确写法

当 codeigniter 3 查询无匹配记录时,`row()->sold_price` 会触发 php 致命错误(因访问 null 对象属性),而非返回 0 或 null;根本原因是链式调用缺乏空值保护,且 `where()` 多参数误用导致 sql 条件拼接错误。

在 CodeIgniter 3 中,$this->db->where() 方法不支持单次调用传入多个条件字段(如你原代码中 ->where(‘category_ID’, $caid,’sold_date >=’,$prev_year_start_month,…))。这种写法会导致 CI 忽略后续参数,仅执行第一个 where(‘category_ID’, $caid),其余日期条件被丢弃——这正是查询“跨年拉取数据”的根源:缺少日期过滤,数据库返回了其他年份的任意匹配记录。

✅ 正确做法是将每个 WHERE 条件拆分为独立的 where() 调用,或使用字符串形式的复合条件:

// ✅ 推荐:清晰、安全、符合 CI 最佳实践
$query = $this->db->select_sum('sold_price')
                  ->from('tbl_sales')
                  ->where('category_ID', $caid)
                  ->where('sold_date >=', $prev_year_start_month)
                  ->where('sold_date <=', $prev_year_end_month)
                  ->group_by('category_ID')
                  ->get();

$result = $query->row();
$sold_price = ($result && isset($result->sold_price)) ? (float)$result->sold_price : 0.0;

⚠️ 注意事项:

天谱乐

天谱乐

唱鸭旗下AI音乐创作平台,为您提供个性化音乐创作体验!

下载

  • 永远不要直接调用 ->row()->xxx:若查询无结果,row() 返回 null,再访问 ->sold_price 将抛出 Trying to get property ‘sold_price’ of non-object 错误;
  • 使用 isset() 或三元判断确保对象存在;
  • 日期字段(如 sold_date)需确保数据库中为 DATE 或 DATETIME 类型,且 $prev_year_start_month、$prev_year_end_month 格式为 ‘Y-m-d’(如 ‘2023-01-01’),避免隐式类型转换
  • 若需兼容无分组场景(如单条记录),可改用 ->row_array() + array_key_exists() 增强健壮性;
  • 避免拼接 SQL 字符串(如第二种答案中的 “category_ID= $caid AND…”),易引发 SQL 注入,除非 $caid 和日期变量已严格过滤(强烈不推荐)。

? 进阶建议:封装为可复用方法,自动处理空值与类型转换:

protected function getSumByDateRange($table, $sum_field, $where_conditions = [], $date_field = 'sold_date', $start = '', $end = '') {
    $this->db->select_sum($sum_field);
    $this->db->from($table);

    foreach ($where_conditions as $key => $value) {
        $this->db->where($key, $value);
    }

    if (!empty($start) && !empty($end)) {
        $this->db->where("{$date_field} >= ", $start);
        $this->db->where("{$date_field} <= ", $end);
    }

    $row = $this->db->get()->row();
    return $row ? (float)($row->$sum_field ?? 0) : 0.0;
}

// 调用示例
$total = $this->getSumByDateRange(
    'tbl_sales', 
    'sold_price', 
    ['category_ID' => $caid], 
    'sold_date', 
    $prev_year_start_month, 
    $prev_year_end_month
);

通过规范 where() 用法 + 主动判空,即可彻底解决“本该返回 0 却报错或返回错误数据”的问题,保障查询逻辑的准确性和系统稳定性。

https://www.php.cn/faq/1974689.html

发表回复

Your email address will not be published. Required fields are marked *