PHP 函数重载
很遗憾, 即使是最新版本的PHP5也不直接支持函数重载. 熟悉JAVA的人都知道, 在JAVA里可以定义多个同名的函数, 只要参数不同即可. 你完全可以轻松做到$a = new javaClass(); $b = new javaClass($arg1); $c = new javaClass($arg1, $arg2); 可是, 在PHP里, 如果你试图定义多个同名函数(如下), 那你的程序运行时将会报错:
class phpClass
{
public function __construct()
{
//do something
}
public funciton __construct($arg1)
{
//do something
}
}
不过, 任何事情总有解决的办法, PHP5给我们提供了强大的'魔术'函数, 使用这些'魔术'函数, 我们也可以做到函数重载. 这里要用到函数是 __call, 看看下面的代码:
class OverLoadTesting
{
public function __construct()
{
$num = func_num_args();
$args = func_get_args();
switch($num){
case 0:
$this->__call('__construct0', null);
break;
case 1:
$this->__call('__construct1', $args);
break;
case 2:
$this->__call('__construct2', $args);
break;
case 3:
$this->__call('__construct3', $args);
break;
default:
throw new Exception();
}
}
public function __construct0()
{
echo "constructor 0" . PHP_EOL;
}
public function __construct1($a)
{
echo "constructor 1: " . $a . PHP_EOL;
}
public function __construct2($a, array $b)
{
echo "constructor 2: " . $a . PHP_EOL;
var_dump($b);
}
public function __construct3(A $a, A $b, C $c)
{
echo "constructor 3: " . PHP_EOL;
var_dump($a, $b, $c);
}
private function __call($name, $arg)
{
return call_user_func_array(array($this, $name), $arg);
}
}
试着运行一下上面的代码吧, 调用各种不同的构造函数,比如 $t = new OverLoadTesting(); $x = new OverLoadTesting('overloaded'); 你会发现, 我们在PHP里也实现了函数重载. 这个__call函数这底是干什么的? 简单来说, 就是能让你调用并不存在的函数!!! 具体的用法查一下PHP手册就明白了.
最后, 我不得不说的是, 这是非常非常非常丑陋的. 个人意见是, 在大型的开发应用中, 我们应该尽量不要使用PHP所提供的这些'魔术'函数, 特别是这个__call. 原因? 上面的例子可能还不明显, 再看一下这个例子:
class Caller
{
private $x = array(1, 2, 3);
public function __call($m, $a)
{
print "Method $m called:n";
var_dump($a);
return $this->x;
}
}
$foo = new Caller();
$a = $foo->test(1, "2", 3.4, true);
var_dump($a);
?>
设想一下当你需要对别人的程序进行修改, 或者DEBUG的时候, 你搜索完所有的文档也没发现到底在哪里定义了这个test()函数的时候, 你会恨不得想杀了写这个程序的人!
至于PHP以后会不会支持函数重载?(哦, 对了, 面向对象的忠实支持者大概会不喜欢'函数',也就是function这个说法吧, 在面向对象的世界里, 我们似乎应该说'方法', method), 这个很难说, 不过, PHP直接支持函数重载的可能性不大, 要实现函数重载, 有两个条件: 第一, 参数的类型不同;第二, 参数的个数不同. 对于第一点, PHP本来是弱类型语言, 在PHP里, 对类型的要求并不严格, 必要时PHP还会自动进行类型转换. 对于第二点, 谁都知道, PHP支持参数缺省, 也就是说, 你定义一个这样的函数 function foo($a=null){}, 你可以这样调用foo(), 也可以foo('test')这样调用.
所以, PHP怕是在短时间内, 不会支持函数重载, 甚至永远也不会.