php Laravel 5雄辩,如何动态设置演员属性

ccgok5k5  于 2023-03-16  发布在  PHP
关注(0)|答案(3)|浏览(150)

在laravel 5.1中有一个新特性叫做属性转换,详细记录如下:http://laravel.com/docs/5.1/eloquent-mutators#attribute-casting
我的问题是,是否可以动态地进行属性强制转换?
例如,我有一个包含列的表:

id | name          | value       | type    |
1  | Test_Array    | [somearray] | array   |
2  | Test_Boolean  | someboolean | boolean |

可以根据type字段设置value属性转换,该属性转换在写入(创建/更新)和获取时都有效。

bogh5gae

bogh5gae1#

您需要在模型类中覆盖Eloquent模型的**getCastType()**方法:

protected function getCastType($key) {
  if ($key == 'value' && !empty($this->type)) {
    return $this->type;
  } else {
    return parent::getCastType($key);
  }
}

您还需要将value添加到**$this-〉casts中,以便Eloquent将该字段识别为castable**。您可以将默认的类型转换放在此处,如果您没有设置type,则将使用该类型转换。

更新日期:

从数据库中阅读数据时,上述方法非常有效。写入数据时,必须确保在value之前设置type。有两个选项:
1.总是传递一个属性数组,其中typekey在valuekey之前--目前模型的fill()方法在处理数据时遵守键的顺序,但它不是面向未来的。
1.在设置其他属性之前显式设置
type
属性。使用以下代码可以轻松完成此操作:

$model == (new Model(['type' => $data['type']))->fill($data)->save();
tvz2xvvm

tvz2xvvm2#

$casts属性在您访问字段时使用,而不是在从数据库获取字段时使用。因此,您可以在填充模型后更新$casts属性,并且在您访问value字段时,它应该可以正常工作。您只需要弄清楚如何在type字段更改时更新$casts属性。
一个可能的选择是重写fill()方法,以便它首先调用父fill()方法,然后使用type字段中的数据更新$casts属性。
另一个可能的选择是滥用mutator功能,并在type字段上创建一个mutator,以便每当它改变时,它将更新$casts属性。

kwvwclae

kwvwclae3#

这里的一些答案确实是想得太多了,或者他们是微妙的错误。
原则是在需要$casts属性之前设置它,例如在向数据库写入或阅读属性之前。
在我的例子中,我需要使用一个配置好的列名并对其进行强制转换。因为PHP不允许在常量表达式中进行函数调用,所以它不能在类声明中设置,所以我只是在模型的构造函数中声明了列/属性的强制转换。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model; 

class MyModel extends Model
{
    protected $casts = [
        // we can't call a function in a class constant expression or
        // we'll get 'Constant expression contains invalid operations'
        // config('my-table.array-column.name') => 'array', // this won't work
    ];

    public function __construct()
    {
        $this->casts = array_merge(
            $this->casts, // we can still use $casts above if desired
            [
                // my column name is configured so it isn't known at
                // compile-time so I have to set its cast run-time;
                // the model's constructor is as good a place as any
                config('my-table.array-column.name') => 'array',
            ]
        );

        parent::__construct(...func_get_args());
    }
}

相关问题