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

Laravel 5 Eloquent查询返回集合所有模型ID均为1的问题排查

问题排查与解决方案

这个问题我之前在Laravel项目里碰到过,核心原因是多表联查时的字段名冲突导致的,咱们一步步拆解:

为什么会出现ID全为1的情况?

你的SQL用了select *,而games和game_vendors表都有id字段。在MySQL终端里,它会把两个id字段分别显示出来(比如列名都是id但对应不同表的数据),但当PHP处理查询结果时,返回的是关联数组——数组的键名是唯一的,后面的id值会直接覆盖前面的。

如果刚好所有符合条件的game_vendors记录的id都是1,那最终所有模型的id就都会被覆盖成1,这就是你看到的异常。

解决方案

方案1:明确指定字段并给冲突字段取别名

不要用select *,手动列出需要的字段,给冲突的字段(比如game_vendors.id)取别名,确保games.id是唯一的id键:

$games = DB::table('games')
    ->select(
        'games.id as id', // 明确保留games的id作为模型的id
        'games.name',
        'games.description',
        'game_vendors.id as vendor_id', // 给供应商id取别名
        'game_vendors.name as vendor_name'
        // 其他你需要的字段
    )
    ->leftJoin('game_vendors', 'games.vendor_id', '=', 'game_vendors.id')
    ->where('game_vendors.name', '!=', 'some_vendor')
    ->whereNotIn('games.id', range(1, 12))
    ->get();

方案2:用Eloquent关联查询(更符合Laravel最佳实践)

如果你的项目里已经定义了Game和GameVendor模型,推荐用Eloquent的关联查询来避免字段冲突:
首先在Game模型里定义关联:

// app/Game.php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Game extends Model
{
    public function vendor()
    {
        return $this->belongsTo(GameVendor::class, 'vendor_id');
    }
}

然后用whereHas来过滤关联模型的条件:

$games = Game::whereHas('vendor', function ($query) {
        $query->where('name', '!=', 'some_vendor');
    })
    ->whereNotIn('id', range(1, 12))
    ->get();

这种方式下,Eloquent会自动处理表字段的映射,不会出现字段覆盖的问题,代码也更易维护。

验证方法

你可以先在Laravel里执行DB::select(你的SQL语句),打印返回的数组,就能看到数组里的id字段已经被覆盖成game_vendors.id的值了,这就能确认问题所在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:02:03