今天在使用laravel的时候碰到个问题,我在模型里面使用了修改器,把type对应的数字变成了显示的中文,像下面这样:
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);
}
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};
}
}
\DB::enableQueryLog();
$res = Course::find($course_type)->value('class_hour');
dd($res, \DB::getQueryLog());
array:2 [
0 => array:3 [
“query” => “select * fromcourse
wherecourse
.id
= ? limit 1”
“bindings” => array:1 [
0 => “4”
]
“time” => 8.43
]
1 => array:3 [
“query” => “selectclass_hour
fromcourse
limit 1”
“bindings” => []
“time” => 7.67
]
]