php class function wrapper
这是我的班级:
1 2 3 4 5 6 7 8 9 10 11 | class toyota extends car { function drive() { } function break() { } } class car { function pre() { } } |
我有什么方法可以这样做,当我运行$ car-> drive(),$ car-> break()(或丰田中的任何其他函数)时,它会先调用$ car-> pre()然后再调用 丰田的功能?
是的。你可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class toyota extends car { protected function drive() { echo"drive "; } protected function dobreak() { echo"break "; } } 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 "; } } $car = new toyota(); $car->drive(); $car->dobreak(); |
http://ideone.com/SGi1g
您可以执行以下操作,但我认为这不是您想要的。
1 2 3 4 5 6 7 8 9 10 11 12 13 | class toyota extends car { function drive() { $this->pre(); } function break() { $this->pre(); } } class car { function pre() { } } |
您可能想要研究PHP特定的魔术方法。 http://php.net/manual/en/language.oop5.magic.php
如果您使用的是PHP5(> = 5.3.2),那么有一种解决方案可以将所有方法声明为私有。这将强制执行单个函数调用的方法调用:
1 | exec_method() |
运行于:http://ideone.com/cvfCXm
代码段在这里:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?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'); ?> |
参考:
回答使用PHPUnit测试受保护方法的最佳实践[关闭]
使用名为__call()的魔术方法可以做得更好
1 2 3 4 5 | public function __call($name, $arguments) { $this -> pre(); return $this -> $name($arguments); } |
这个方法是什么?它会覆盖默认方法调用,以便可以调用
你的
1 2 3 4 5 6 7 8 9 10 11 12 13 | class toyota extends car { public function __call($name, $arguments) { $this -> pre(); return call_user_func_array(array($this, $name), $arguments); } function drive() { } function break() { } } |
只需添加一个构造函数,就像这样......
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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(); |
Classes which have a constructor method call this method on each
newly-created object, so it is suitable for any initialization that
the object may need before it is used.