如何访问类的静态成员?

50
我试图访问一个类的静态成员。
我的类是:

```

class MyClass {
public:
    static int myStaticInt;
};

```

class A
{
    public static $strName = 'A is my name'
    public function xyz()
    {
        ..
    }
    ..
}
//Since I have bunch of classes stored in an array
$x = array('A');
echo $x::$strName;

我在打印时遇到了错误。如何打印'A is my name'


我认为你想要在数组中实例化A类的实例,而不是字符'A'(它没有名为strName的静态成员)。 - Jacob
我有一个类列表存储在数组中,需要遍历它。 - KoolKabin
静态成员通过方法调用比反射更好。 - KoolKabin
5个回答

116
如果 A 是一个类,你可以直接通过 A::$strName 来访问它。
class A {
    public static $strName = 'A is my name';
}

echo A::$strName; // outputs "A is my name"

更新:

根据你的数组里面包含的内容,无论是我所定义的类对象还是类字面值可能是一个因素。我通过以下方式区分这两个术语:

$objClasses = array(new A(), new B()); // class objects
$myClasses = array('A','B');           // class literals
如果你采用类字面量的方法,那么在使用 PHP5.2.8 的 foreach 循环以及使用范围解析运算符时会出现语法错误。
foreach ($myClasses as $class) {
     echo $class::$strName;
  //syntax error, unexpected '::', expecting ',' or ';'
}

那么我考虑使用类对象的方法,但是实际上我唯一能够输出静态变量的方式是使用对象实例和关键字 self ,像这样:

class A {
    public static $strName = 'A is my name';

    function getStatic() {
        return self::$strName;
    }
}

class B {
    public static $strName = 'B is my name';

    function getStatic() {
        return self::$strName;
    }
}

然后在迭代时调用该方法,

foreach($objClasses as $obj) {
    echo $obj->getStatic();
}

那么为什么要在声明变量时使用static呢?这完全违背了无需实例化对象即可访问变量的整个思想。

简而言之,当我们获得更多关于您想要做什么的信息时,我们就可以提供更好的答案。


我有一个类列表存储在数组中,需要遍历它们。因此,我需要使用数组来访问它们。 - KoolKabin
我不太明白,你想做什么? - Anthony Forloney
看起来没错。请参考http://www.php.net/manual/en/language.oop5.static.php。这就是我想要记住的内容。 - James McLeod
我甚至尝试了给出的示例,但它仍然给我错误。我使用的是PHP版本5.2。 - KoolKabin
@KoolKabin 我正在使用 PHP 5.2.8 并且在我的浏览器上运行得很好。您能否实际发布一下您想要做什么?看起来您尝试做的有点混乱,如果提供更多信息可能会更清楚些。您是否拥有一个类数组?例如 array(new A(), new B()) - Anthony Forloney

10
如果你想要一个适用于PHP5.2的工作版本,你可以使用reflection来访问一个类的静态属性。
class A {
    static $strName= '123';
}

$lstClass = array('A');
    
foreach ($lstClass as $value) {
    $c = new ReflectionClass($value);
    echo $c->getStaticPropertyValue('strName');
}

演示:http://ideone.com/HFJCW

2

您有一个语法错误,缺少分号,并且因为它是一个数组,您需要访问索引0,否则它将尝试调用类“Array”。

class A
{
    public static $strName = 'A is my name';

    public function xyz()
    {
        // left blank and removed syntax error
    }
}
$x = array('A');
echo $x[0]::$strName;

应该修复它。

更新

如果你想遍历一个数组来调用一个类变量:

$x = array('A', 'B');
foreach ($x as $class) {
     echo $class::$strName;
}

我不确定为什么您想要这样做,但是这就是您需要的。经过测试,没有出现错误,并且收到了有效响应A is my name

编辑

显然,这只适用于PHP 5.3及以上版本。


这是针对已删除的评论的一条提示:我通过php -a cli 工具进行了测试,效果非常好。我修改了代码以删除...,以避免出现语法错误。并且,B类需要被创建才能正确运行 UPDATE 部分的代码。 - Jim
没关系,ideone.com正在使用PHP5.2,在PHP5.3下也能正常工作。 - HoLyVieR

1

如果在类内部想要访问自己的静态数据成员,您也可以使用 static:: 而不是 self::


0

我发现下一个简单的解决方案,但不知道是否好用。

我的解决方案是:

eval('return '.$x[0].'::$strName;');

2
我不会太依赖 eval,因为它可能会有危险。 - Anthony Forloney
如果我们只使用固定的预定义命令,那么它是否可以被视为邪恶? - KoolKabin
说实话,作为个人偏好,我甚至不会使用预定义命令。不,按照你现在的方式做并不应该是“邪恶”的,但我知道有更好的解决方案。 - Anthony Forloney
是的,使用那个会非常有问题。例如,如果找不到类,这将只会创建一个致命错误,使整个脚本停止而没有任何捕获错误的可能性。如果您使用反射,它将会抛出一个可以被捕获的异常。 - HoLyVieR
谢谢建议。那么反射方法比其他方法更好,是吗? - KoolKabin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接