PHP提出面向对象以来,就有着各种各样的问题,其中,不直接支持对象方法重载就是一个让人纠心的问题,在其他语言里面,大可以有以下写法(以下是C++写法):
class Abc(){ public function a( int x){ cout<<x<<endl; } public function a( int x , int y){ cout<<x<<endl; cout<<y<<endl; } } Abc aa = new Abc(); aa.a(1);//1 aa.a(1,2)//1 2
这些方法,在某些时候是非常有用的。可是,在PHP里面如果 你直接在一个类里面定义两个函数名一样的函数(即使他们的参数个数不一样),是会报错的。
所以对于PHP我们要实现方法重载就只能另辟他径了,下面我给出两种方式:
一、利用__call函数
在 PHP 中的方法调用是这样工作的。首先,PHP 解释器在类上查找方法。如果方法存在,PHP 就调用它。如果没有,那么就调用类上的魔术函数 __call(如果这个方法存在的话)。如果 __call 失败,就调用父类方法,依此类推。看下面的例子:
class OverloadTest{ public function __call($name,$para){ if($name=='construct'){ switch (count($para)){ case 0: $this->cons1(); break; case 1: $this->cons2($para[0]); break; default: print "wrong para"; } }else{ print 'Undefined method '.$name; } } function cons1(){ echo "cons1() called"; } function cons2($var){ echo "cons2() called."; } } $foo = new OverloadTest(); $foo->construct(); $foo->construct('test');
二、使用func_get_args()和func_num_args()函数获取参数个数
这两个函数分别是获取函数的参数列表及参数长度。根据参数长度,我们可以有跟上面一样的做法,但是这个方法看起来更和谐点。看下面的例子:
class OverloadTest{ public function __construct{ $args = func_get_args(); switch (func_num_args()){ case 0: $this->_cons1(); break; case 1: $this->_cons2($args[0]); break; default: print "wrong para"; } } private function _cons1(){ echo "cons1() called"; } private function _cons2($var){ echo "cons2() called."; } } $foo = new OverloadTest(); $foo->construct(); $foo->construct('test');
两种方式都算是比较容易的实现了函数重载,但是这种模拟的做法也只是临时之计,希望PHP在未来面象对象的实现能够更全面一些。