Laravel使用点表示法合并两个数组

问题描述 投票:2回答:1

我认为我的大脑今天没有运作,因为我似乎无法理解这一点。

我有一个有数据数组的类,例如 -

class Testing {

    protected $fillable = ['questions.*.checked'];

    protected $data = [
        'active' => true,
        'questions' => [
            [
                'question' => 'This is the first question',
                'checked' => true,
            ],
            [
                'question' => 'This is the second question',
                'checked' => false,
            ]
         ]
    ];

    public function fill(array $attributes = []) {
        // take our attributes array, check if the key exists in
        // fillable, and if it does then populate our $data property
    }

}

我想要做的是,如果我将以下数组传递给Testing::fill()方法,它只会更新被认为是可填充的相应属性。

例如,传递以下数组

[
    'active' => false,
    'questions' => [
        [
            'question' => 'This is the first question',
            'checked' => true,
        ],
        [
            'question' => 'This is the second question',
            'checked' => true,
        ]
    ]
]

只修改对象上的已检查标志,其他所有内容都将被忽略 - 仅将属性$ data attribute questions.*.checked标记为true

我觉得有一个解决方案使用Laravel的助手,但我似乎无法接受它,或者我可能走错了方向......

最后,我只想要一定程度的消毒,这样当整个结构被发回到对象填充方法时,只有某些项目才能真正得到更新(就像Laravel的填充方法,更深入的动态值)。问题是$ data中实际包含的是动态的,所以可能有一个问题,可能有100个......

arrays laravel-5.7
1个回答
1
投票

好吧,我已经找到了一个可以完成这项工作的解决方案,但我希望有一些更多的Laravel中心。


protected function isFillable($key)
{
    // loop through our objects fillables
    foreach ($this->fillable as $fillable) {

        // determine if we have a match
        if ($fillable === $key
            || preg_match('/' . str_replace('*', '([0-9A-Z]+)', $fillable) . '/i', $key)
        ) {
            return true;
        }
    }

    // return false by default
    return false;
}

public function fill(array $attributes = [])
{
    // convert our attributes to dot notation
    $attributes = Arr::dot($attributes);

    // loop through each attribute
    foreach ($attributes as $key => $value) {

        // check our attribute is fillable and already exists...
        if ($this->isFillable($key)
            && !(Arr::get($this->data, $key, 'void') === 'void')
        ) {

            // set our attribute against our data
            Arr::set($this->data, $key, $value);
        }
    }

    // return ourself
    return $this;
}

所以,在上面,当我调用fill()方法时,我正在使用Arr::dot()将所有属性转换为Laravel的点符号。这使得数组更容易循环,并允许我执行我正在寻找的那种检查。

然后我创建了一个isFillable()方法来确定属性键是否存在于我们的对象$fillable属性中。如果涉及到通配符,它​​会将星号(*)转换为正则表达式,然后检查是否存在匹配。在执行正则表达式之前,它会执行基本的比较检查,理想情况下希望绕过正则表达式并尽可能提高整体性能。

所以,最后,如果我们的属性是可填充的,并且我们已经能够从我们的数据数组中获取值,那么我们将使用Arr::set()更新此值

© www.soinside.com 2019 - 2024. All rights reserved.