$fillable只控制写入权限,不控制输出;查不到字段主因是$hidden隐藏、$casts转换失败或访问器返回null,需通过dd($model->getattributes())与dd($model->toarray())对比定位。

为什么 $fillable 字段赋值后查不到?
因为 Laravel 的模型属性默认只读写「可填充」字段,但「返回给前端」或 toArray() 时,仍受 $hidden、$casts、访问器(accessor)和序列化配置影响。你填进去了,不等于它会吐出来。
-
$fillable只控制「能不能通过create()或fill()写入」,不控制「会不会出现在 JSON/数组中」 - 如果字段在
$hidden里,哪怕已成功存库,toArray()和 API 响应里也直接消失 - 如果字段没加到
$casts且是 JSON 类型或布尔/整型,可能被转成字符串或 null,看起来像“没返回” - 自定义访问器(如
getFooAttribute())若逻辑出错(比如 return null),也会导致该字段为空
toArray() 不包含某字段的排查顺序
别急着改 $fillable,先确认数据流卡在哪一环:
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
- 查数据库:用
dd($model->fresh())看原始模型实例,确认字段是否真存进去了 - 看隐藏规则:检查
$hidden数组是否误含该字段,或$visible是否未显式列出它 - 看访问器:搜索
get{FieldName}Attribute方法,临时注释掉,测试是否恢复显示 - 看强制转换:
$casts中若把status设为'integer',但数据库存的是字符串'1',Laravel 5.8+ 会静默失败并返回 null
只写不读字段的正确做法:用 $appends + 访问器,而非依赖 $fillable
如果你本意就是「允许写、但不该从模型直接读取」(比如密码哈希、临时 token),就别把它塞进 $fillable 后又期待它出现在响应里——这本身就是矛盾设计。
- 真正只写的字段,应走
setAttribute()手动处理,或用setXxxAttribute()在存入时加工,不设访问器 - 如果只是「写入时需要、读取时不展示」,就把它加进
$hidden,而不是指望$fillable控制输出 - 如果要「写入后生成一个衍生值用于返回」(如写入
password_raw,返回is_password_set),用$appends = ['is_password_set']+ 对应访问器,干净分离职责
Laravel 9+ 的 $casts 静默失败陷阱
新版本对类型转换更严格,但错误不报异常,只返回 null,极易误判为“没存进去”或“没返回”。
- 比如字段名是
is_active,数据库类型是TINYINT(1),但$casts = ['is_active' => 'boolean']时,若存入字符串'0'或空格,Laravel 会转成null而非false - 解决办法:统一用整型存布尔(
'is_active' => 'int'),或确保入库前已过滤($request->boolean('is_active')) - 调试时加一行:
var_dump($model->getAttributes()['is_active'], $model->getAttribute('is_active')),区分原始值和 cast 后值
$hidden、$casts 和访问器三者叠加造成的“透明丢失”。盯住 dd($model->getAttributes()) 和 dd($model->toArray()) 的差异,比翻文档更快定位问题。










