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

Laravel 8集合返回错误ID,是框架BUG还是操作失误?

结论

这不是Laravel框架的BUG,属于PDO底层的默认行为,是查询写法的预期结果。

原因说明

当你执行JOIN查询同时使用*查询两个表的所有字段时,peoples表和companies表存在同名字段id,PHP底层的PDO扩展在返回结果集时,会将同名字段做覆盖处理:后查询的companies表的id值会覆盖先查询的peoples表的id值。
你在phpMyAdmin中查询结果正常,是因为phpMyAdmin在渲染结果时会自动加上表前缀区分同名字段,而原生PDO以及基于PDO封装的Laravel数据库操作层不会做自动区分,同名字段仅会保留最后出现的对应值。

推荐解决方案

除了你提到的手动指定必要字段的方案外,还有两种更易用的写法:

  1. 给同名字段加别名
    如果需要保留两个表的所有字段,只需给同名字段单独指定别名即可避免覆盖:
$clients = People::select('peoples.*', 'companies.id as company_id', 'companies.*')
    ->join('companies', 'peoples.company_id', '=', 'companies.id')
    ->where('companies.is_active', '>', 0)
    ->orderBy('company')
    ->get();
  1. 使用Eloquent关联预加载(更推荐)
    直接在People模型中定义关联关系,不用手动写JOIN,完全避免字段冲突问题:
    首先在app/Models/People.php中定义关联:
public function company()
{
    return $this->belongsTo(Company::class);
}

查询时直接使用whereHas+with即可:

$clients = People::whereHas('company', function ($query) {
    $query->where('is_active', '>', 0);
})->with('company')->orderBy('company.company')->get();

这种写法返回的结果中,人员自身的字段都在根层级,关联的公司数据会放在单独的company属性下,完全不会出现同名字段覆盖的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:54:02