能否创建不关联数据库表的Laravel Model 用于存储永不变更的静态数据
实现方案
你的需求完全可以实现,Laravel的扩展性可以完美支持这种静态数据模型的诉求,既保留Eloquent的全部特性,又可以避免数据库表数据被篡改的风险,以下是两种常用的落地方式:
方案1:使用Sushi扩展(最简实现)
Sushi是专门为Laravel提供静态数组驱动的Eloquent扩展,不需要创建数据库表,数据直接定义在模型内部,天然支持所有Eloquent查询语法。
实现步骤:
- 安装扩展:
composer require calebporzio/sushi - 创建静态模型:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Sushi\Sushi; class LogLevel extends Model { use Sushi; // 关闭时间戳 public $timestamps = false; protected $guarded = []; // 定义静态数据,此处即为所有日志等级的全量数据 protected $rows = [ ['name' => 'Emergency', 'icon' => 'fas fa-ambulance', 'color' => 'red'], ['name' => 'Alert', 'icon' => 'fas fa-bullhorn', 'color' => 'yellow'], ['name' => 'Critical', 'icon' => 'fas fa-heartbeast', 'color' => 'orange'], // 剩余等级数据在此补充即可 ]; // 重写所有写入方法,彻底禁止修改操作 public function save(array $options = []): bool { throw new \RuntimeException('LogLevel为静态数据模型,不支持写入操作'); } public function delete(): bool { throw new \RuntimeException('LogLevel为静态数据模型,不支持删除操作'); } public static function update(array $attributes = [], array $options = []): int { throw new \RuntimeException('LogLevel为静态数据模型,不支持更新操作'); } public static function destroy($ids): int { throw new \RuntimeException('LogLevel为静态数据模型,不支持删除操作'); } }
使用方式:
你可以像操作普通数据库模型一样使用它,支持所有Eloquent查询语法:
- 获取所有日志等级:
LogLevel::all() - 条件查询:
LogLevel::where('color', 'red')->first() - 关联其他模型:正常定义
hasMany/belongsTo等关联方法即可
方案2:原生实现(无第三方依赖)
如果不想引入外部扩展,你也可以自行重写Eloquent的查询逻辑,将数据作为静态属性存储在模型中,替换默认的数据库查询驱动即可。核心逻辑是将模型的查询指向预定义的数组数据,同时屏蔽所有写入操作,实现效果和Sushi完全一致。
两种方案的静态数据都完全存储在模型代码文件内,不会生成对应的数据库表,只要通过代码版本控制和服务器文件权限限制模型文件的修改权限,就完全不会出现数据被篡改的问题,同时保留了Eloquent的访问器、修改器、关联、查询构造器等全部特性。
内容的提问来源于stack exchange,提问作者Ron Butcher
相关产品推荐
相关产品推荐

