如何使用 PHP 反射来设置静态属性?

问题描述 投票:0回答:2

我正在使用 PHPUnit 制作一个模拟类进行测试。

class Item extends Object {
  protected static $_cache;
}

我非常确定嘲笑会做类似的事情(如果我错了,请纠正我):

class Mock_Item_randomstring extends Item {

}

当我的

Item
的缓存被填充时,它会检查传入的对象是否是
Item
的实例。由于模拟没有显式定义
$_cache
,因此它无法检查实例类型。

PHP 根本没有很好地记录反射函数。有没有办法在事后设置静态变量,这样类就会变成

class Mock_Item_randomstring extends Item {
  protected static $_cache;
}

编辑

我尝试了反射方法并遇到了各种问题。这是我感到困惑的一个:

$mock = $this->getMock( 'Item', array( '_func' ), array(
  $argument1, $argument2
));

$mock = new ReflectionClass($mock); 


$mock->staticExpects( $this->exactly(2) )->method( '_func' );

我假设反思会复制整个班级。我收到此错误:

Call to undefined method ReflectionClass::staticExpects()

php phpunit
2个回答
0
投票

我倾向于对子类中的每个类静态变量使用有点令人讨厌的技巧:

class A {
    protected static $cache;
    public static function getCache() {
        return static::$cache;
    }
    public static function setCache($val) {
        static::$cache = & $val; // note the '&'
    }
}
class B extends A {}

A::setCache('A');
B::setCache('B');
A::getCache(); // 'A'
B::getCache(); // 'B'

当然,最好一开始就避免使用静态变量。使用专用的缓存对象并在类实例化时注入它。


0
投票

你不必这样做。

\Closure::bind
允许您读取和分配私有和受保护的静态属性。请参阅 http://www.php.net/manual/en/closure.bind.php

上的示例代码
© www.soinside.com 2019 - 2024. All rights reserved.