7.4+:
Хорошая новость в том, что это будет реализовано в новых выпусках, как указал @Andrea. Я просто оставлю это решение здесь на случай, если кто-то захочет использовать его до версии 7.4.
7.3 или меньше
Основываясь на уведомлениях, которые я все еще получаю из этой темы, я полагаю, что у многих людей была / есть та же проблема, что и у меня. Мое решение для этого случая заключалось в объединении сеттеров + __set
магического метода внутри трейта, чтобы имитировать это поведение. Вот:
trait SettersTrait
{
/**
* @param $name
* @param $value
*/
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; //It could be implemented within this class but I used it as a trait for more flexibility
/**
*
* @var Bar
*/
private $bar;
/**
* @param Bar $bar
*/
protected function setBar(Bar $bar)
{
//(optional) Protected so it wont be called directly by external 'entities'
$this->bar = $bar;
}
}
$foo = new Foo();
$foo->bar = new NotBar(); //Error
//$foo->bar = new Bar(); //Success
Пояснение
Прежде всего, определите bar
как частное свойство, чтобы PHP применял __set
автоматически.
__set
проверит, объявлен ли какой-либо сеттер в текущем объекте (method_exists($this, $setter)
). В противном случае он только установит свое значение, как обычно.
Объявите метод установки (setBar), который получает аргумент типа (setBar(Bar $bar)
).
Пока PHP обнаруживает, что что-то, что не является экземпляром Bar
, передается сеттеру, он автоматически вызывает фатальную ошибку: Uncaught TypeError: аргумент 1, переданный в Foo::setBar(), должен быть экземпляром Bar, экземпляр NotBar задан
person
CarlosCarucce
schedule
19.06.2018