php类函数包装器

php类函数包装器,php,oop,Php,Oop,这是我的班级: class toyota extends car { function drive() { } function break() { } } class car { function pre() { } } 有什么方法可以让我在运行$car->drive()、$car->break()或丰田的任何其他函数时,在调用丰田的函数之前,它会先调用$car->pre()。您可以执行以下操作,但我认为这不是您想要的 class toyot

这是我的班级:

class toyota extends car {
    function drive() {
    }
    function break() {
    }
}

class car {
    function pre() {
    }
}

有什么方法可以让我在运行$car->drive()、$car->break()或丰田的任何其他函数时,在调用丰田的函数之前,它会先调用$car->pre()。

您可以执行以下操作,但我认为这不是您想要的

class toyota extends car {
    function drive() {
         $this->pre();
    }
    function break() {
         $this->pre();
    }
}

class car {
    function pre() {
    }
}

您可能希望了解特定于PHP的魔术方法

是的。您可以使用
保护
和一些
\u调用
魔术:

class toyota extends car {
    protected function drive() {
        echo "drive\n";
    }
    protected function dobreak() {
        echo "break\n";
    }
}

class car {
    public function __call($name, $args)
    {
        if (method_exists($this, $name)) {
            $this->pre();
            return call_user_func_array(array($this, $name), $args);
        }


    }

    function pre() {
        echo "pre\n";
    }
}

$car = new toyota();
$car->drive();
$car->dobreak();

只需添加一个,就像这样

class toyota extends car {
    function __construct() { 
        $this->pre();
    }   

    function drive() {
        echo "drive!";
    }

    function dobreak() {
        echo "break!";
    }
}

class car {
    function pre() {
        echo "Hello!";
    }
}

$car = new toyota();
$car->drive();
$car->dobreak();
具有构造函数方法的类在每个 新创建的对象,因此它适用于 该对象在使用前可能需要


break
是保留的,因此不应将其用作函数名。

这最好使用名为uu call()的神奇方法

这个方法是什么?它覆盖默认的方法调用,因此可以调用
preCall
状态

您的
toyota
课程

class toyota extends car {    

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

    function drive() {
    }
    function break() {
    }
}
如果您使用的是PHP5(>=5.3.2),那么有一个解决方案可以将所有方法声明为私有。这将强制从单个函数调用执行方法调用:

exec_method()
运行时间:

代码片段如下所示:

<?php

    class car {

        //method to get class method
        public function get_method($method_name) {
            $class = new ReflectionClass(get_class($this));
            $method = $class->getMethod($method_name);
            $method->setAccessible(true);
            return $method;
        }

        public function exec_method($method_name, $arg_args=array()) {

            //execute the pre() function before the specified method
            $this->pre();

            //execute the specified method
            $this->get_method($method_name)->invokeArgs($this, $arg_args);
        }

        public function pre() {
            echo 'pre';
            echo '<br />';
        }
    }

    class toyota extends car {
        private function drive() {
            echo 'drive';
            echo '<br />';
        }

        private function brake() {
            echo 'brake';
            echo '<br />';
        }
    }

    $toyota = new toyota();
    $toyota->exec_method('drive');
    $toyota->exec_method('brake');
?>

参考:


阅读“构造函数”函数……这可能是您需要的。您能澄清一下吗?我不知道您是想在创建新对象时运行$car->pre(),还是在调用$car方法时运行。下面的答案涵盖了这两个方面——我只是不知道要修改哪一个。我想他正在寻找一种方法,在函数调用之前运行方法
pre
,而不是在对象初始化时。在回答时,我被打断了。我已经用构造函数更新了我的示例。这不仅是使用uu调用(正确的方法)的唯一答案,也是唯一一个真正执行某些方法存在检查并实际调用最初调用的方法的答案。做这个!你是说私人的而不是受保护的?“原因受保护”仍然可以由父级看到并继承。@sberry,使用方法_exists()进行检查将隐藏调用invalid时收到的默认错误methods@Starx:是的,但是如果方法不存在,您可以抛出本机错误或exception@Patrick:不,
private
不起作用,因为父类没有访问祖先的私有方法的权限,
$this->$name($arguments)
---将使用作为数组传递的所有参数调用请求的方法。因此,
$car->drive(1,2)
将使用
$car->drive(数组(1,2))
重新调用,这是不正确的
<?php

    class car {

        //method to get class method
        public function get_method($method_name) {
            $class = new ReflectionClass(get_class($this));
            $method = $class->getMethod($method_name);
            $method->setAccessible(true);
            return $method;
        }

        public function exec_method($method_name, $arg_args=array()) {

            //execute the pre() function before the specified method
            $this->pre();

            //execute the specified method
            $this->get_method($method_name)->invokeArgs($this, $arg_args);
        }

        public function pre() {
            echo 'pre';
            echo '<br />';
        }
    }

    class toyota extends car {
        private function drive() {
            echo 'drive';
            echo '<br />';
        }

        private function brake() {
            echo 'brake';
            echo '<br />';
        }
    }

    $toyota = new toyota();
    $toyota->exec_method('drive');
    $toyota->exec_method('brake');
?>