【问题标题】:Access the arguments passed to child method访问传递给子方法的参数
【发布时间】:2015-01-02 19:09:56
【问题描述】:

我有以下:

class bar {

    function __construct(){

         // set $a_from_fire to $a from fire() method arg
         // set $b_from_fire to $b from fire() method arg
    }
}

class foo extends bar {

    function fire ($a, $b){

    }
}

我需要使用来自 foo->fire() 的参数设置 $a_from_fire 和 $b_from_fire

如果我这样做:

$test = new foo;
$test->fire(1, 2);

这些变量将被设置:

$a_from_fire == 1; // true
$b_from_fire == 2; // true

【问题讨论】:

  • 你的问题不是很清楚:s
  • 我不确定你到底想做什么。您至少可以显示一些无效的代码或进一步的描述来解释您想要的内容吗?另外,$a_from_fire 声明在哪里?
  • 我刚刚添加了一些说明。我正在尝试调试一组作为消息队列中的作业运行的类。它们都扩展了一个父类,所以我希望我可以通过简单地向父类添加一个方法来记录传递给每个子类方法的参数以捕获参数。
  • 也许这可以用 __construct 以外的东西来完成?
  • 我昨天也遇到了this post,这可能会有所帮助,但考虑到您的特殊情况,这听起来并没有帮助(因为您必须在父类之外重写一些代码)。

标签: php class inheritance


【解决方案1】:

我认为你不能以任何“正确”的方式做到这一点。我的第一个想法是使用__call,但当然只为未定义的函数调用。

实际上没有任何方法可以动态地rename the methods,除非您已经在使用RunKit。 (不是我知道或无论如何都能找到的)。

如果纯粹出于调试目的,您可以设置自己的类自动加载器来预处理文件,更改方法名称,然后在父类上使用 __call 魔术方法。

spl_autoload_register(function($class){
       $hackPath = '/home/_classes/'.$class;
       if (!file_exists($hackPath)){
           $realPath = '/home/classes/'.$class;
           $file = file_get_contents($realPath);
           $processedContent = //use regex or something to prepend all function names with an _.
           file_put_contents($hackPath,$processedContent);
       }


       require_once $hackPath;
    });

然后在你的父类中

class parent {

    public function __call($funcName,$arguments){

       $this->myLogFunc($funcName,$arguments);
       //since you prepended with an underscore
       return call_user_func_array('_'.$funcName,$arguments);

    }

这是一种很糟糕的方式来做你所要求的,但它可以工作。文件的预处理可能会很慢,但您只需要在原始文件更改时进行(您可以使用filemtime 来检查它是否已更改)。

【讨论】:

    【解决方案2】:

    这是不可能的,因为__construct() 在对象第一次实例化时被调用,所以fire($a, $b) 将始终运行之后 __construct()

    如果您只想在调用fire() 时设置变量,只需这样做:

    class bar {
        protected $a_from_fire;
        protected $b_from_fire;
    }
    
    class foo extends bar {
        public function fire($a, $b) {
            $this->a_from_fire = $a;
            $this->b_from_fire = $b;
        }
    }
    

    【讨论】: