访问PHP类常量

访问PHP类常量,php,oop,Php,Oop,PHP手册上说 与静态成员一样,无法从对象实例访问常量值 这就解释了为什么你不能这么做 $this->inst = new Classname(); echo $this->inst::someconstant; 但为什么这样做有效呢 $this->inst = new Classname(); $inst = $this->inst; echo $inst::someconstant; 引用手册: 从PHP5.3.0开始,可以使用变量引用该类。变量的值不能是关键字(

PHP手册上说

与静态成员一样,无法从对象实例访问常量值

这就解释了为什么你不能这么做

$this->inst = new Classname();
echo $this->inst::someconstant;
但为什么这样做有效呢

$this->inst = new Classname();
$inst = $this->inst;
echo $inst::someconstant;
引用手册:

从PHP5.3.0开始,可以使用变量引用该类。变量的值不能是关键字(例如self、parent和static)

它接着使用这个例子:

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

因此,
$inst::someconstant
应该可以工作


至于为什么
$this->inst::someconstant
会出现解析错误,我不知道。PHP在某些方面很有趣。

来自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的主干中已经修复,但我不知道它们是否也修复了双冒号语法。)

如果你在类中,您可以按如下方式访问常量:

self::MY_CONSTANT;
例如:

class MyClass {
    const MY_CONSTANT = 'constant value';

    public function showConstant() {
        echo self::MY_CONSTANT;
    }
}

php支持从对象实例访问类常量。以下代码正在运行(在phpv5.5.5中检查):


$inst::someconstant
是有效的语法,但它真的能工作吗?所以它真的可以归结为php解析器中的一个bug,在以后的版本中会得到修复?这要么是疏忽,要么是有意的决定。我不确定我会称之为虫子。PHP内部人员倾向于认为人们很容易混淆,因此他们尽量避免使用可能“模棱两可”的语法。双冒号也用于表示静态方法;对类的实例调用静态方法是完全没有意义的。也就是说,如果他们要限制这种行为,那将是一个运行时错误,而不是解析错误。是的,已经十年了,没有人应该再使用PHP5了,但下面是一个基于此示例的3v4l,它表明问题在PHP7+中得到了解决:
<?php
class superheroes{
    const kal_el = 'Superman';
}

$instance = new superheroes;
echo $instance::kal_el;