无法使用:: scope运算符从实例访问类常量

时间:2012-08-15 20:31:32

标签: php

我今天遇到了一个奇怪的问题,即使作为一名PHP工程师,我也很难过:

您似乎可以从对象实例访问类常量,例如:

class a {
    const abc = 1;
}
$a = new a();
var_dump($a->abc);

这将输出null而不是预期的1.我能够执行以下操作:

class a {
    const abc = 1;
}
$a = new a();
var_dump(a::abc);

但是在一个不完全知道父母是谁的子对象的上下文中,我发现它非常烦人:

class a {
    const abc = 1;
}
$a = new a();
$c = get_class($a);
var_dump($c::abc);

是我还是这是完全愚蠢的,如果没有,请告诉我为什么它的工作方式。

修改

另一种方法,但不是更好:

class a {
    const abc = 1;
}
class b {
    public function getA(){
        return new a();
    }
}
$b = new b();
$c = $b->getA();
var_dump($c::abc);

最后一个例子更像我正在做的和体验...

6 个答案:

答案 0 :(得分:13)

只需将实例变量与范围解析运算符一起使用:

$a = new a();
var_dump($a::abc);

prints 1

答案 1 :(得分:9)

我找到了一种相对简洁的方法来让我的问题更容易生活。这是我应用的解决方案。它不一定是最好的,但对于我的用途,它完全符合我的需要。

通过创建一个魔法__get方法,我从实例的角度截取常量名称的请求,并使用快速反射来查看该常量是否存在并返回它的值。

这使我能够在一行中实际使用如下所示的模式:

class a {
    const abc = 1;
    public function __get($key){
        $r = new ReflectionObject($this);
        if($r->hasConstant($key)){ return $r->getConstant($key); }
    }
}
class b {
    public function getA(){
        return new a();
    }
}
$b = new b();
var_dump($b->getA()->abc);
var_dump($b->getA()->def);

虽然我喜欢这样做:

var_dump($b->getA()::abc);
var_dump($b->getA()::def);

我想这可能会在5.4以后发生,考虑到我们最终有阵列解除引用,我们可能会要求他们尽快添加静态解除引用。

答案 2 :(得分:4)

The PHP documentation表示通过SRO(::)而不是->访问类常量。

<?php
class MyClass
{
    const constant = 'constant value';

    function showConstant() {
        echo  self::constant . "\n";
    }
}

echo MyClass::constant . "\n";

答案 3 :(得分:2)

我提到过,在常量中,常量与类定义联系在一起,根据定义它们是静态的,无法使用 - &gt;进行访问。操作

如果您真的想在编码范例中使用它,可以在php5中尝试反射类。

class MyClass
{
   const A = "I am A";
}

$o = new ReflectionClass( "MyClass" );
echo $o->getconstant("A"); //will print "I am A"

另外,我认为 EDIT 中的示例可能无法正常工作..我没有运行它,但我不确定是否可以在任何不能运行的东西上调用SRO(::)一个班级参考..

答案 4 :(得分:2)

我知道这是一个旧线程,但对于想要了解最佳方法的人来说,请查看PHP函数constant()

使用constant(),您只需执行此操作:

$a = new a();
$value = constant(get_class($a)."::abc");
// $value === 1

自PHP 4开始提供此功能,并且仍可在PHP 5.5中完美运行

答案 5 :(得分:0)

尝试使用在不同命名空间中的类中定义的const时,可以使用范围解析运算符::),而不会出现{{3 }}在声明const的类之前使用以下格式在名称空间前添加前缀:

  • (<namespace>"\")*<className>::<const>

使用下一个名称空间,类和const定义:

models / OperationModel.php

<?php
namespace models;

class OperationModel {
  const OPERATION_INITIALIZING = 1;
}

您可以像这样使用来自另一个命名空间\类的const:

controllers / MobileController.php

<?php
namespace controllers;

use models\OpertionModel;

class MobileController {
  private function thingy() {
    $operation_status = models\OperationModel::OPERATION_INITIALIZING;
  }
}