0

本质上,我希望有一个通用的“漏斗”类型的自动日志记录。这是简短的描述,实际上假设我们有一个 Controller 类,现在就像在 codeIgniter 中一样,一切都几乎通过 Controller 运行,但是我想创建一些东西,通过这个类将所有请求汇集到 Controller 以进行通用日志记录。这是一个例子......

class Base {
    protected $_controller;

    public function __construct() {
        $this->_controller = new Controller();
    }
    public function __get($key) {
        $this->_logger->log('you are getting '.$key);
        return $this->_controller->$key;
    }
    // and so on for all the magic methods, __set, __get, __call, __callStatic
}

这里的问题是 __call 方法,因为它使 args 成为一个数组,如果我必须将 2 个 args 传递给控制器​​,它会破坏一切,即

    public function __call($method, $args) {
        //obviously call to logging and make sure method_exists here
        return $this->_controller->$method($args);
    }

但是,如果该方法需要两个这样的参数怎么办...

    //this would be inside the Controller
    public function get_stats($start_date, $end_date) {
        //blah blah lots of code here
    }

如果我然后调用 Base->get_stats('2011-01-01', '2013-10-19') 一切都会中断,因为只有 1 个 arg 传递给 Controller 方法,因为 __call 如何将所有 args 加入一个数组。显然,如果我知道总会有 2 个 args,那么我只会得到 $args[0] 和 $args[1] 但这里的理论是让它真正动态化,以便所有函数调用都通过 Base 类和Controller 中的函数可能有 1-1 百万个参数。有没有人有任何想法?我试过call_user_func_array,但它试图以静态方式调用类中的所有方法,即

//inside base class
public function __call($method, $args) {
    //check for function and all that stuff here
   return call_user_func_array(array($this->_controller, $method), $args);
}

会抛出错误,因为 Controller 中的方法是非静态的。我很茫然,但我真的很想完成这项工作,所以有什么想法吗?谢谢,麻烦您了。

4

1 回答 1

1

call_user_func_array应该可以正常工作,因此您必须在代码的其他地方做错了什么:

<?php
    class Base {
        private $controller;

        public function __construct() {
            $this->controller = new Controller();
        }

        public function __call($method, $arguments) {
            return call_user_func_array(array($this->controller, $method), $arguments);
        }

        public static function __callStatic($method, $arguments) {
            return call_user_func_array(array('Controller', $method), $arguments);
        }
    }

    class Controller {
        public function fooMethod($foo, $bar) {
            return array($foo, $bar);
        }

        public static function barMethod($bar, $foo) {
            return array($bar, $foo);
        }
    }

    $base = new Base();

    $result = $base->fooMethod('foo', 'bar');

    print_r($result);

    $result = Base::barMethod('bar', 'foo');

    print_r($result);
?>

输出:

Array
(
    [0] => foo
    [1] => bar
)
Array
(
    [0] => bar
    [1] => foo
)

演示

于 2013-10-31T15:39:22.420 回答