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

如何在Laravel模型中创建虚拟计算列?

在Laravel模型中创建虚拟(计算)列的几种实现方式

完全可行,以下是几种满足你需求的实现方案:

方案1:访问器 + $appends 属性(模型层面计算)

这是最常用的方式,能让title_body自动出现在Post::all()等查询的结果中:

  1. 在Post模型里定义访问器,实现字段拼接逻辑:
public function getTitleBodyAttribute()
{
    return $this->title . ' ' . $this->body;
}
  1. 将这个自定义属性添加到模型的$appends数组,确保它会被包含在模型的数组/JSON输出中:
protected $appends = ['title_body'];

这种方式是在PHP层面完成计算,数据从数据库取出后再处理,适合数据量不大、逻辑简单的场景。

方案2:查询构造器 + selectRaw(数据库层面计算)

如果追求性能(尤其是大数据量场景),可以让数据库直接返回计算后的字段:
直接在查询中指定:

$posts = Post::select('*', DB::raw("CONCAT(title, ' ', body) as title_body"))->get();

如果想让所有Post模型的查询都自动带上这个字段,可添加全局作用域:
在Post模型的boot方法中添加:

protected static function boot()
{
    parent::boot();

    static::addGlobalScope('title_body', function ($query) {
        $query->select('*', DB::raw("CONCAT(title, ' ', body) as title_body"));
    });
}

之后调用Post::all()、Post::find()等方法时,结果都会自动包含title_body字段,这种方式性能更优。

方案3:Laravel 9+ 自定义列简化写法

Laravel 9及以上版本可以结合addSelect在模型中统一处理,本质和全局作用域思路一致,比如在模型中定义:

protected static function boot()
{
    parent::boot();

    static::addSelect([
        'title_body' => DB::raw("CONCAT(title, ' ', body)")
    ]);
}

效果和方案2的全局作用域一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:15:03