来自兄弟的保护区访问
Protected fields access from brother
我揭示了 php >= 5.2
的有趣行为
class A {
protected $a = 'A';
public function __get($f){ return 'field_'.$f; }
}
class B extends A {}
class C extends A {
public function foo() {
$b = new B();
echo $b->a;
}
}
$c = new C();
$c->foo();
我希望它打印 field_a
,但它打印 A
.
还。如果我从 A
中删除魔法 - 我预计会出现致命错误,但它仍会在 php>=5.2
中打印 A
。
如果我们覆盖 B::$a
,我们会得到另一种行为 - fatal error
。
为什么?
是功能还是错误?
小提琴:
- http://3v4l.org/tiOC5 - 获取外部字段
- http://3v4l.org/uT9PC - 出现致命错误
我相信如果你声明一个变量它不会使用 __get
魔术方法。
因此,通过声明 protected $a = 'A';
,您将从 __get
循环中排除 a
。它将跳过魔术方法并直接进入实际的 属性.
如果您查看魔术方法 __get() and __set() 的文档,您会发现它们仅 运行 在 reading/writing 无法访问的字段的情况下。
在您的示例中,$a
可从 class C
访问,因为它被定义为受保护的字段(inheriting/parent 类 可以查看受保护的 fields/methods)。如果您将 $a
更改为私有字段,它应该必须为您的示例调用魔术方法。
这是因为 PHP 关于谁可以和不能访问 class 属性的非常时髦的规则。
在这里阅读:
http://php.net/manual/en/language.oop5.visibility.php
关键部分是这样的:
The visibility of a property or method can be defined by prefixing the
declaration with the keywords public, protected or private. Class
members declared public can be accessed everywhere. Members declared
protected can be accessed only within the class itself and by
inherited and parent classes. Members declared as private may only be
accessed by the class that defines the member.
强调我的。您可以访问任何继承自相同 class 的对象的受保护变量,即使在另一个对象上也是如此。这还包括访问完全相同的其他对象的私有属性 class.
这是一个好主意还是一个奇怪的功能还有待商榷,但它似乎是有意为之。
我揭示了 php >= 5.2
的有趣行为class A {
protected $a = 'A';
public function __get($f){ return 'field_'.$f; }
}
class B extends A {}
class C extends A {
public function foo() {
$b = new B();
echo $b->a;
}
}
$c = new C();
$c->foo();
我希望它打印 field_a
,但它打印 A
.
还。如果我从 A
中删除魔法 - 我预计会出现致命错误,但它仍会在 php>=5.2
中打印 A
。
如果我们覆盖 B::$a
,我们会得到另一种行为 - fatal error
。
为什么?
是功能还是错误?
小提琴:
- http://3v4l.org/tiOC5 - 获取外部字段
- http://3v4l.org/uT9PC - 出现致命错误
我相信如果你声明一个变量它不会使用 __get
魔术方法。
因此,通过声明 protected $a = 'A';
,您将从 __get
循环中排除 a
。它将跳过魔术方法并直接进入实际的 属性.
如果您查看魔术方法 __get() and __set() 的文档,您会发现它们仅 运行 在 reading/writing 无法访问的字段的情况下。
在您的示例中,$a
可从 class C
访问,因为它被定义为受保护的字段(inheriting/parent 类 可以查看受保护的 fields/methods)。如果您将 $a
更改为私有字段,它应该必须为您的示例调用魔术方法。
这是因为 PHP 关于谁可以和不能访问 class 属性的非常时髦的规则。
在这里阅读:
http://php.net/manual/en/language.oop5.visibility.php
关键部分是这样的:
The visibility of a property or method can be defined by prefixing the declaration with the keywords public, protected or private. Class members declared public can be accessed everywhere. Members declared protected can be accessed only within the class itself and by inherited and parent classes. Members declared as private may only be accessed by the class that defines the member.
强调我的。您可以访问任何继承自相同 class 的对象的受保护变量,即使在另一个对象上也是如此。这还包括访问完全相同的其他对象的私有属性 class.
这是一个好主意还是一个奇怪的功能还有待商榷,但它似乎是有意为之。