laravel collection 的问题

方楷
2023-12-01

今天在使用laravel的时候碰到个问题,我在模型里面使用了修改器,把type对应的数字变成了显示的中文,像下面这样:

1、collection的坑

public function getTypeAttribute($value)
{
 $labelType = [
    1 => '个性',
    2 => '风格',
    3 => '用户评论标签',
 ];
 return $labelType[$value]??'';
}

然后再使用collection进行筛选的时候就出问题了,

public function getLabels($type = 0)
{
    $data = Label::where('status', 1)->get();
    $need = (object) [];
    if ($type == 1) {
        $need->character = $data->where('type', 1);
        $need->style = $data->where('type', 2);
        $need->customer_give_label = $data->where('type', 3);
        return $need;
    }
    return $data;
}

结果发现$need取不到值,让我疑惑的不是这里,二是我在这里打印$data的时候里面的不论是attributes还是original里面的type都还显示的是数字!这个就有点匪夷所思了。

然后我就想到了要去
D:\phpStudy\WWW\xxx\vendor\laravel\framework\src\Illuminate\Support\Collection.php
直接查看 construct ,可以看到,这个就说明在使用collection进行筛选的时候,第一部就把转成数组了,难道是在这个时候修改器起作用了?一般说来,对于单个数据,修改器作用在attributes里面,而原始数据放在original里面,但是取出的结果是个列表的时候,情况就变了,original和sttributes里面的都是原始数据。所以,这里尤其要注意,我认为这是个bug,等空了在gitHub上提个issue.

public function __construct($items = [])
{
    $this->items = $this->getArrayableItems($items);
}

bug2:ORM里面的value方法,这个也是有坑

D:\phpStudy\WWW\xxx\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php
进到这里面可以看到,value方法是这么说的,value方法可以取到结果集里面的第一个数据指定的column,但是实际上,却不是这么回事。我在使用find之后,链式连接value方法,结果变成了到那个表里面去查询第一个数据的这个column了。。。这就比较尴尬了,这也是不太容易发现的地方,这里记录一下,后续提issue,然后更新。

/**
 * Get a single column's value from the first result of a query.
 *
 * @param  string  $column
 * @return mixed
 */
public function value($column)
{
    if ($result = $this->first([$column])) {
        return $result->{$column};
    }
}

code:

\DB::enableQueryLog();
$res = Course::find($course_type)->value('class_hour');
dd($res, \DB::getQueryLog());

result:

array:2 [
0 => array:3 [
“query” => “select * from course where course.id = ? limit 1”
“bindings” => array:1 [
0 => “4”
]
“time” => 8.43
]
1 => array:3 [
“query” => “select class_hour from course limit 1”
“bindings” => []
“time” => 7.67
]
]

 类似资料: