PHP的方法重载实现

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在未来面象对象的实现能够更全面一些。

 

posted @ 2014-05-17 13:02  zernmal  阅读(470)  评论(0编辑  收藏  举报