PHP5.0 属性与方法重载以及可能遇到的问题
PHP5支持更强大的重载了,通过覆盖__call、__get、__set方法,可以实现属性和方法的重载。利用PHP本身的动态特性,可以实现非常灵活的重载机制。
<?php
class Example {
public function method1($arg1) {
echo "This is method1 with argument {$arg1}\n";
}
public function method2($arg1, $arg2) {
echo "This is method2 with argument {$arg1} and {$arg2}\n";
}
public function __call($method, $args) {
$targetMethod = array($this, $method.count($args));
if(is_callable($targetMethod)) {
call_user_func_array($targetMethod, $args);
}
}
private $readonlyProperty = 100;
public function __get($varName) {
if(isset($this->$varName)) {
return $this->$varName;
}
}
}
$example = new Example();
$example->method(100); //call method with 1 arg
$example->method(100, 200); //call method with 2 args
echo $example->readonlyProperty; //get and output the readonlyProperty
$example->readonlyProperty = 200; //try to set value for readonlyProperty will cause a problem
?>
class Example {
public function method1($arg1) {
echo "This is method1 with argument {$arg1}\n";
}
public function method2($arg1, $arg2) {
echo "This is method2 with argument {$arg1} and {$arg2}\n";
}
public function __call($method, $args) {
$targetMethod = array($this, $method.count($args));
if(is_callable($targetMethod)) {
call_user_func_array($targetMethod, $args);
}
}
private $readonlyProperty = 100;
public function __get($varName) {
if(isset($this->$varName)) {
return $this->$varName;
}
}
}
$example = new Example();
$example->method(100); //call method with 1 arg
$example->method(100, 200); //call method with 2 args
echo $example->readonlyProperty; //get and output the readonlyProperty
$example->readonlyProperty = 200; //try to set value for readonlyProperty will cause a problem
?>
我也开始在新的项目中尝试利用重载机制优化开发工作,但发现伴随而来的两个新问题。第一个问题是重载属性之后,PHP的empty函数不好用了。
如果在上面的代码中增加这样一句,本来readonlyProperty确实存在,值也是非空的值(100),但是empty函数总是返回false。大概是因为empty函数是一个PHP编译后的函数,调用的时候不会触发__get方法执行,才导致这样的结果。
第二个问题是PHP的方法重载只支持实例方法重载,静态方法依然无法重载。
最近在PHP官方网站上找资料,发现在新的版本中,已经解决了上面所述的两个问题。从PHP5.1开始,新增__isset和__unset两个方法的重载,__isset会在调用PHP的检查空值函数empty或检查变量是否设置函数isset时触发,而__unset则由变量删除函数unset触发。从PHP5.3开始,新增__callStatic方法重载,支持重载静态方法。但是,到目前截止,PHP依然不支持重载类的静态属性。