Когда мы используем 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 использует при печати такого объекта?