父系中后代气泡中的静态变量赋值?

时间:2012-11-19 11:35:58

标签: php static aop class-hierarchy

我遇到了一个问题,我不确定这是不是正常的行为,或者我是否写错了。我的基类中有一个方法,通过为该特定类的所有新实例创建代理,将全局过滤器应用于给定的类。我计划进行的方式如下:

  1. static $global_filter(代理)附加到我想要过滤的类,这扩展了基类object
  2. 通过我的加载机制,在新的实例化时返回代理而不是实际的类(这将掩盖方法调用并相应地应用过滤器)。
  3. 但是,我陷入第1步,似乎当我尝试将static $global_filter分配给我想要过滤的后代类时,我的基类object也是获得相同的任务,从而打破从其延伸的所有其他任务。

    请参阅下面的相关代码:

    class object {
    
        public static $global_filter;
    
        public function _filterGlobal($class, $method, $callback) {
            if ( !is_object($class::$global_filter) ) {
                $class::$global_filter = new filterable(null);
                # Replace the object being called with the new proxy.
            }
            var_dump($class);
            var_dump($class::$global_filter); // `filterable`
            var_dump(\core\blueprint\object::$global_filter); // Returns same as line above
            die();
            return $class::$global_filter->_add($method, $callback);
        }
    
    }
    

    $class::$global_filter\core\blueprint\object::$global_filter(基类)都返回相同的实例。我希望 object::$global_filter为空

    我没有使用后期静态绑定来保持一致性(单个对象过滤器和全局过滤器以非静态方式调用很多)。

    This question seems relevant

    任何帮助将不胜感激:)

    编辑,完整示例

    这将是一个具体的类,它扩展model,扩展object

    <?php
    use core\blueprint\model;
    class modelMock extends model {
        protected $schema = array();
        public function method($test) {
            return $test;
        }
    }
    

    这将是另一个对象(例如控制器),它也会扩展object。它将过滤器应用于model

    的所有新实例
    <?php
    use core\blueprint\object;
    class objectMock extends object {
    
        public function applyFilters() {
            $this->_filterGlobal('core\blueprint\model', 'method', function($self, $chain) {
                $chain->params[0] = 'new param'; // adjust the paramters
                return $chain->next();
            });
        }
    
    }
    

3 个答案:

答案 0 :(得分:1)

  

当我尝试将静态$ global_filter分配给我想要过滤的后代类时,我的基类对象也得到相同的赋值

是的,确实会发生这种情况。静态属性本质上是一个全局变量,受限于类的命名空间。遇到全局变量问题通常表明您没有使用最佳解决方案。

要解决您的问题,您可以将过滤器设为(非静态)属性:

$class->$filter = new Whatever();

但与往常一样,有更多的道路通往罗马,我建议你寻找替代方法。

答案 1 :(得分:1)

我不知道这对你有帮助:

class a {
   public static $type;

   public static function setType($class, $newType) {
      $class::$type = $newType;
      var_dump($class::$type);
   }
}
class b {
   public static $type = 'myType';
}

var_dump(b::$type);
a::setType('b', 'yourType');
var_dump(a::$type);

您可能没有将静态属性定义为具体类。

答案 2 :(得分:1)

感谢大家的帮助,今天早上我花了一些时间来解决我的问题。这是一个解决方法,但这是如何:

public function _filterGlobal($class, $method, $callback) {
    if ( !is_object($class::$global_filter[$class]) ) {
        $class::$global_filter[$class] = new filterable(null);
        # Replace the object being called with the new proxy.
    }
    return $class::$global_filter[$class]->_add($method, $callback);
}

因此,基本上为了获得在子类中工作的唯一静态变量而不必显式定义它们,您可以使用一个数组将子类的名称存储为键,然后通过getter访问这些变量。