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

Laravel 11开启shouldBeStrict后自定义属性报Undefined array key错误

修复Laravel严格模式下自定义属性Undefined array key错误

问题出在开启Model::shouldBeStrict()后,模型的$attributes数组会严格校验键的存在——你的自定义属性select和mediaData并非数据库字段,首次加载模型时$attributes里没有这些键,直接通过$this->attributes['select']访问就会触发错误。

以下是几种可行的修复方案:

方案1:在Getter中使用安全访问

修改属性的获取方法,添加默认值兜底,避免直接访问不存在的数组键:

// Get select value.
public function getSelectAttribute(): bool
{
    return $this->attributes['select'] ?? false;
}

// Get mediaData value.
public function getMediaDataAttribute(): array
{
    return $this->attributes['mediaData'] ?? [];
}

这种方式最简单,直接在Getter里处理不存在的情况,给属性设置合理的默认值(比如select默认false,mediaData默认空数组)。

方案2:模型加载时初始化属性

利用模型的retrieved事件,在每次模型从数据库取出后自动初始化自定义属性,确保$attributes里存在对应的键:

protected static function boot()
{
    parent::boot();
    if(App::isLocal()) {
        Model::shouldBeStrict();
    }

    // 模型加载后初始化自定义属性
    static::retrieved(function ($currency) {
        if (!array_key_exists('select', $currency->attributes)) {
            $currency->setSelectAttribute(false);
        }
        if (!array_key_exists('mediaData', $currency->attributes)) {
            $currency->setMediaDataAttribute([]);
        }
    });
}

这种方式能保证每次模型实例化后,$attributes里都有自定义属性的键,后续访问不会报错。

方案3:使用类属性存储临时值

既然这些是运行时的临时属性(非数据库字段),没必要存在$attributes数组里,直接用类的私有属性存储更规范:

class Currency extends Model implements HasMedia
{
    protected $table = 'currencies';
    protected $primaryKey = 'id';
    public $timestamps = false;
    protected $appends = ['select', 'mediaData'];

    // 用类属性存储临时值
    private ?bool $select = false;
    private array $mediaData = [];

    protected static function boot()
    {
        parent::boot();
        if(App::isLocal()) {
            Model::shouldBeStrict();
        }
    }

    // Set select value.
    public function setSelectAttribute(bool $value): void
    {
        $this->select = $value;
    }
    // Get select value.
    public function getSelectAttribute(): bool
    {
        return $this->select;
    }

    // Set mediaData value.
    public function setMediaDataAttribute(array $value): void
    {
        $this->mediaData = $value;
    }
    // Get mediaData value.
    public function getMediaDataAttribute(): array
    {
        return $this->mediaData;
    }
}

这种方式彻底脱离$attributes数组,完全避开严格模式的限制,同时符合临时属性的设计逻辑,推荐用于非数据库字段的自定义属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 10:05:14