larval toArray
之前开发的时候遇到的一个问题
数据库查出来的对象在没toArray之前遍历,针对关联的模型里的字段进行重新重组,发现一个问题,取到的关联的模型始终是null,随查看了下源码,才知道关联模型如果是驼峰式的,在toArray的时候才会转为下划线方式,在这之前依然是驼峰式的。
public function relationsToArray()
{
$attributes = [];
foreach ($this->getArrayableRelations() as $key => $value) {
if ($value instanceof Arrayable) {
$relation = $value->toArray();
}
elseif (is_null($value)) {
$relation = $value;
}
if (static::$snakeAttributes) {
$key = Str::snake($key);
}
if (isset($relation) || is_null($value)) {
$attributes[$key] = $relation;
}
unset($relation);
}
return $attributes;
}
public static function snake($value, $delimiter = '_')
{
$key = $value;
if (isset(static::$snakeCache[$key][$delimiter])) {
return static::$snakeCache[$key][$delimiter];
}
if (! ctype_lower($value)) {
$value = preg_replace('/\s+/u', '', ucwords($value));
$value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
}
return static::$snakeCache[$key][$delimiter] = $value;
}
举个栗子:
$list = (new AgentCostomerRelations())
->with([
'users' => function ($query) {
return $query->select(['id', 'nickname', 'true_name', 'telephone', 'created_at']);
},
'agent' => function ($query) {
return $query->select('user_id', 'level');
},
'userNameRemark',
'userGroupMap'
])->get();
if ($list->isEmpty()) return [];
foreach ($list as &$info) {
$info['group_id'] = $info->userGroupMap->group_id ?? '';
}
unset($info);
var_dump($list->toArray());exit;
之前在遍历的时候用下划线的方式去访问group_id
一直访问不到,这个时候改为驼峰式的才可以访问的得到,还有一个地方就是如果是分页查询,在没有toArray()之前返回的值是没有data这个字段的,是因为这个时候返回的对象是分页的对象,而不是model,最终调用toArray()方法的时候转换,不过这个toArray方法是分页对象自己的toArray方法,\Illuminate\Pagination\LengthAwarePaginator
public function toArray()
{
return [
'current_page' => $this->currentPage(),
'data' => $this->items->toArray(),
'first_page_url' => $this->url(1),
'from' => $this->firstItem(),
'last_page' => $this->lastPage(),
'last_page_url' => $this->url($this->lastPage()),
'next_page_url' => $this->nextPageUrl(),
'path' => $this->path,
'per_page' => $this->perPage(),
'prev_page_url' => $this->previousPageUrl(),
'to' => $this->lastItem(),
'total' => $this->total(),
];
}