7.4+:
Хороша новина, що це буде впроваджено в нових випусках, як зазначила @Andrea. Я просто залишу це рішення тут, якщо хтось захоче використовувати його до 7.4
7,3 або менше
На основі сповіщень, які я все ще отримую від цієї теми, я вважаю, що багато людей там мали / мають таку ж проблему, як і я. Моє рішення для цього випадку поєднання сеттери + __set
магічний метод всередині ознаки для того , щоб змоделювати цю поведінку. Ось:
trait SettersTrait
{
public function __set($name, $value)
{
$setter = 'set'.$name;
if (method_exists($this, $setter)) {
$this->$setter($value);
} else {
$this->$name = $value;
}
}
}
І ось демонстрація:
class Bar {}
class NotBar {}
class Foo
{
use SettersTrait;
private $bar;
protected function setBar(Bar $bar)
{
$this->bar = $bar;
}
}
$foo = new Foo();
$foo->bar = new NotBar();
Пояснення
Перш за все, визначте bar
як приватну власність, щоб PHP передавав __set
автоматично .
__set
перевірить, чи є в поточному об'єкті ( method_exists($this, $setter)
) встановлений деякий сеттер . В іншому випадку він лише встановить своє значення, як зазвичай.
Оголосіть метод сетера (setBar), який отримує аргумент із натяком на тип ( setBar(Bar $bar)
).
Поки PHP виявляє, що щось, що не є Bar
екземпляром, передається установщику, воно автоматично запускатиме Фатальну помилку: Uncaught TypeError: Аргумент 1, переданий Foo :: setBar (), повинен бути екземпляром Bar, екземпляром NotBar, заданим