是的,如果您的代码不是开源的,否则不是。
不检查对象的实例并不能确保方法 getUser() 返回的对象将具有您期望的所有方法(例如:getUsername())。
如果您查看Controller.php 中的getUser() 方法,它不一定会返回用户对象。事实上,你可以设置 Symfony2 防火墙,让getUser() 返回不同实例的不同对象。
承认我们有一个定义getUsername()的接口UserInterface。
在下面的代码中,我们的 User 对象没有实现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();
}
如果有人扩展了 User 对象,那么 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;接口是设定期望和避免重大问题的好方法。
当您阅读代码时,您可以快速识别所传递的对象的类型。如果有人更改代码,它要么显示一个有意义的错误,要么优雅地降级(在这种情况下,用户将被拒绝访问)。