是的,如果你的代码不是开源的,否则没有。
不检查对象的实例并不能确保方法getUser()
返回的对象将拥有您所期望的所有方法(例如:getUsername()
)。
如果您查看Controller.php中的getUser()
方法,它不一定会返回用户对象。事实上,您可以设置Symfony2防火墙,getUser()
将返回不同实例的不同对象。
承认我们有一个接口UserInterface
,它定义了getUsername()
。
在以下代码中,我们的用户对象不执行UserInterface
。
$user = $this->getUser();
if (!is_object($user)) {
$user->getUsername();
}
此代码将抛出一个错误,因为getUsername()
不会在对象上存在,而不是代码应该是以下几点:
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
$user->getUsername();
}
如果用户对象没有实现正确的接口,则代码不会出错,因为它不会被执行。
避免检查类似下面的
$user = $this->getUser();
if (!is_object($user) || !$user instanceof User) {
$user->getRoles();
}
对象如果有人扩展了用户对象,然后if语句将不再执行,因为$user
不会是User
实例,但说ExtendedUser
即使它有所有你需要的方法。
使用接口的另一个优点是可以在对象上实现多个接口。
class A implements C {}
class B extends A implements C, D {}
interface C {}
interface D {}
$nA = new A();
$nB = new B();
$nA instanceof A; // true - instance of A
$nA instanceof B; // false - pretty obvious, no relationship with B
$nA instanceof C; // true - A implements C
$nA instanceof D; // false - A does not implement D
$nB instanceof A; // false - B is not an instance of A
$nB instanceof B; // true - instance of B
$nB instanceof C; // true - A implements C, that's the key:
// both A and B implements C but B is not an
// instance of A.
$nB instanceof D; // true - A implements D
TLDR;接口是设置期望并避免重大难题的好方法。
当您通读代码时,您可以快速识别传递的对象的类型。如果有人更改了代码,它将显示一个有意义的错误,或者会优雅地降级(在这种情况下,用户将被拒绝访问)。
这不是为了快速交换类,而是为了确保这些类必须实现所需的方法,以便现有代码可以在需要时调用这些方法,并且不需要破解源代码以满足您的需求自己的类 – DarkBee
接口不允许多重继承,在PHP中没有多继承。 – Stev