使用 Tinker CLI 时,Laravel 如何查找并显示 Eloquent 模型上的动态属性?

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


>>> (object) ['hello' => 'world']

 => {

      +"hello": "world",

    }


>>> App\User::first()

 => App\User {

      id: 1,

      name: "...",

   }

对我来说不太明显的是如何使这些虚拟属性出现在这里,就好像它们已经被定义为类的公共属性一样。我知道模型的大部分属性分配都是由该HasAttributes特征在内部处理的,但即使查看那里,我仍然不明白 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 打印这样的对象时,我们如何更改它使用的表示形式?


大话西游666
浏览 80回答 2
2回答

牛魔王的故事

决定如何在 Tinker 中显示模型属性的代码位于 Tinker 代码中,而不是模型中:https://github.com/laravel/tinker/blob/2.x/src/TinkerCaster.phpCasters 是Symfony VarDumper 组件的一部分, PsySH使用该组件来显示类。Tinker 是建立在 PsySH 之上的。Tinker 将脚轮映射到其 Console 命令类中的类:https://github.com/laravel/tinker/blob/2.x/src/Console/TinkerCommand.php这将返回类到其施法者的映射:/**     * 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属性:<?phpnamespace 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'];}

慕容3067478

Eloquent 使用设置的数据库连接自动填充模型属性。
打开App,查看更多内容
随时随地看视频慕课网APP