3

当我们使用artisan tinker, 并引用一个 Eloquent 模型对象时,REPL 会自动打印模型的属性,就像它打印我们引用的任何标准对象的公共属性一样:

>>> (object) ['hello' => 'world']
 => {
      +"hello": "world",
    }

>>> App\User::first()
 => App\User {
      id: 1,
      name: "...",
   }

对我来说不太明显的是如何使这些虚拟属性出现在这里,就好像它们已经被定义为类的公共属性一样。我知道模型的大部分属性分配都是由HasAttributestrait 在内部处理的,但是即使看那里,我仍然看不到 Laravel 的作者是如何实现这种行为的。

我试过建立一个这样的类:

class Bunch implements Arrayable, ArrayAccess, Jsonable, JsonSerializable { ... }

但即使使用有效的数组访问和toArray方法,当我直接从以下位置引用它时artisan tinker

>>> $b = new Bunch()
 => Bunch {}
>>> $b->one = 1
 => 1
>>> $b['one']
 => 1
>>> $b
 => Bunch {}

我们如何改变 REPL 在打印这样的对象时使用的表示?

4

2 回答 2

2

确定如何在 Tinker 中显示模型属性的代码在 Tinker 代码中,而不是在模型中:

Casters 是Symfony VarDumper 组件的一部分,PsySH使用它来显示类。Tinker 建立在 PsySH 之上。

Tinker 将脚轮映射到其控制台命令类中的类:

这将类的映射返回到它们的施法者:

/**
     * Get an array of Laravel tailored casters.
     *
     * @return array
     */
    protected function getCasters()
    {
        $casters = [
            'Illuminate\Support\Collection' => 'Laravel\Tinker\TinkerCaster::castCollection',
            'Illuminate\Support\HtmlString' => 'Laravel\Tinker\TinkerCaster::castHtmlString',
            'Illuminate\Support\Stringable' => 'Laravel\Tinker\TinkerCaster::castStringable',
        ];

        if (class_exists('Illuminate\Database\Eloquent\Model')) {
            $casters['Illuminate\Database\Eloquent\Model'] = 'Laravel\Tinker\TinkerCaster::castModel';
        }

        if (class_exists('Illuminate\Foundation\Application')) {
            $casters['Illuminate\Foundation\Application'] = 'Laravel\Tinker\TinkerCaster::castApplication';
        }

        return $casters;
    }

这将设置 VarDumper 上的脚轮:

        $config->getPresenter()->addCasters(
            $this->getCasters()
        );

如果要从模型中添加其他属性以在 Tinker 中显示,可以使用模型上的 $ appends属性:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = ['is_admin'];
}
于 2021-04-01T22:35:25.423 回答
-1

Eloquent 使用数据库连接设置自动填充模型属性。

于 2020-07-30T08:02:12.380 回答