2011-03-27 73 views
15

PHP手册说访问PHP类常量

像静态成员,恒定值不能从对象的实例进行访问。

这也解释了为什么你不能做到这一点

$this->inst = new Classname(); 
echo $this->inst::someconstant; 

但后来为什么这项工作?

$this->inst = new Classname(); 
$inst = $this->inst; 
echo $inst::someconstant; 
+0

'$研究所:: someconstant'有效*语法*,但它的实际工作? – deceze 2011-03-27 06:10:22

+0

在我的测试中它确实。 – pettazz 2011-03-27 06:13:14

回答

17

从PHP交互shell:

php > class Foo { const A = 'a!'; } 
php > class Bar { public $foo; } 
php > $f = new Foo; 
php > $b = new Bar; 
php > $b->foo = $f; 
php > echo $b->foo::A; 
PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting ',' or ';' in php shell code on line 1 

前者语法失败是PHP解析器不知道如何解决财产引用后双冒号的原因。不管这是否是有意的,都是未知的。

后者语法有效,因为它不是通过属性直接进入,而是通过一个局部变量,其解析器接受的东西能一起工作:

php > $inst = $b->foo; 
php > echo $inst::A; 
a! 

(顺便说一句,这同样限制是到位对于匿名函数作为属性,你不能直接使用parens调用它们,你必须先将它们分配给另一个变量,然后从那里调用它们,这已在PHP的trunk中修复,但我不知道它们是否也修复了双冒号语法)

+0

所以它真的可以归结为PHP解析器中的一个错误,它将在更高版本中修复? – pettazz 2011-03-27 06:23:57

+1

这是一个疏忽或有意的决定。我不确定我会把它称为一个错误。 PHP内部人士倾向于认为人们很容易混淆,所以他们尽量不要让可能的“模糊”语法通过。双冒号也用于指静态方法;在一个类的实例上调用一个静态方法将是完全荒谬的。也就是说,如果他们要限制* that *行为,那将是一个运行时错误,而不是* parse *错误。 – Charles 2011-03-27 06:27:39

7

引述手册:

作为PHP 5.3.0的,有可能使用变量来引用类。变量的值不能是关键字(例如self,parent和static)。

它接着用这个例子:

$class = new MyClass(); 
echo $class::constant."\n"; // As of PHP 5.3.0 

所以$inst::someconstant应该工作。

至于为什么$this->inst::someconstant给出解析错误,我不知道。 PHP对某些事情很有趣。