Laravel中toArray()方法使用驼峰变量

前言

不知道大家在用Laravel开发过程中有没有遇到过模型查询时,with中使用驼峰命名变量名,但是使用toArray方法后,变量名变成了蛇形命名;

比如说这样的一条查询语句:

WorkflowModel::query()->with(['workflowsInfo'])->get()->toArray();

查询出来的结果可能就是这样的:

查询出来关联表的结果key变成了workflows_info这种蛇形命名方式
当然直接这样使用也是没有问题的,但是如果有需要比如说想直接使用key为workflowsInfo的情况,那有没有办法能处理呢?


使用的版本:

  • PHP: 8.1.13
  • Laravel: 10.13.5

通过查看laravel源码
web/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1636

public function toArray()
{
    return array_merge($this->attributesToArray(), $this->relationsToArray());
}

然后查看relationsToArray方法;

...
public static $snakeAttributes = true;
...
public function relationsToArray()
{
    $attributes = [];

    foreach ($this->getArrayableRelations() as $key => $value) {
        // If the values implement the Arrayable interface we can just call this
        // toArray method on the instances which will convert both models and
        // collections to their proper array form and we'll set the values.
        if ($value instanceof Arrayable) {
            $relation = $value->toArray();
        }

        // If the value is null, we'll still go ahead and set it in this list of
        // attributes, since null is used to represent empty relationships if
        // it has a has one or belongs to type relationships on the models.
        elseif (is_null($value)) {
            $relation = $value;
        }

        // If the relationships snake-casing is enabled, we will snake case this
        // key so that the relation attribute is snake cased in this returned
        // array to the developers, making this consistent with attributes.
        if (static::$snakeAttributes) {
            $key = Str::snake($key);
        }

        // If the relation value has been set, we will set it on this attributes
        // list for returning. If it was not arrayable or null, we'll not set
        // the value on the array because it is some type of invalid value.
        if (isset($relation) || is_null($value)) {
            $attributes[$key] = $relation;
        }

        unset($relation);
    }

    return $attributes;
}
...

从代码中可以看到有个公共的变量,只要将这个公共的变量设置为false,就可以不用蛇形变量,保持原有的变量名;

所以这里给出下面两种方案来处理:

方案一

使用默认不转变的方法,来实现:

...
class WorkflowModel extends BaseModel
{
    use HasDateTimeFormatter;
    use SoftDeletes;

    protected $table = 'workflows';

    public static $snakeAttributes = false;

    ...
}

方案二

也可以使用静态方法设置的方式来改变$snakeAttributes的变量

...
class WorkflowModel extends BaseModel
{
    use HasDateTimeFormatter;
    use SoftDeletes;

    protected $table = 'workflows';
    public static function setNotSnakeAttributes(): Builder
    {
        parent::$snakeAttributes = false;
        return static::query();
    }

    ...
}
WorkflowModel::setNotSnakeAttributes()->with(['workflowsInfo'])->get()->toArray();

以上就是暂时想到的两种方案,大家如果有更好的想法,可以留言一起讨论。

posted @ 2024-02-02 16:47  Sillager  阅读(282)  评论(0)    收藏  举报