7.4+:
如@Andrea所指出的,好消息是它将在新版本中实现。如果有人想在7.4之前使用它,我将在此处保留此解决方案。
7.3以下
根据我仍然从该线程收到的通知,我相信很多人都遇到过/正在遇到与我相同的问题。 对于这种情况,我的解决方案是在特征中结合使用setter和__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
说明
首先,将__set定义为私有属性,以便PHP将自动转换method_exists($this, $setter)。
__set将检查当前对象中是否声明了某些设置器(method_exists($this, $setter))。 否则,它将仅照常设置其值。
声明一个接收带有类型提示参数的setter方法(setBar)(Bar)。
只要PHP检测到非Bar实例正在传递给setter,它将自动触发致命错误:Uncaught TypeError:传递给Foo :: setBar()的参数1必须是Bar的实例,NotBar的实例 给定