该系列我只写我的理解,非官方解释,如不够专业请见谅
PHP有很多魔术方法,比如__autoload
就是一个。这里主要介绍的是__invoke
、__call
、__callStatic
这3个方法
invoke
PHP5.3新增了一个叫做__invoke
的魔术方法,这样在创建实例后,可以直接调用对象
<?php
class A
{
public function __invoke($str)
{
print "A::__invoke(): {$str}";
}
}
$a = new A;
$a("Hello World");//输出'HelloWorld'
call&&callStatic
php 5.3 后新增了 __call
与__callStatic
魔法方法。
__call
当要调用的方法不存在或权限不足时,会自动调用__call
方法。
__callStatic
当调用的静态方法不存在或权限不足时,会自动调用__callStatic
方法。
<?php
class Member{
protected $memberdata = array();
public function __call($func, $arguments){
list($type, $name) = explode('_', $func);
if(!in_array($type, array('set','get')) || $name==''){
return '';
}
switch($type){
case 'set':
$this->memberdata[$name] = $arguments[0];
break;
case 'get':
return isset($this->memberdata[$name])? $this->memberdata[$name] : '';
break;
default:
}
}
}
class User extends Member{
public function show(){
if($this->memberdata){
foreach($this->memberdata as $key=>$member){
echo $key.':'.$member.'<br>';
}
}
}
}
class Profession extends Member{
public function show(){
if($this->memberdata){
foreach($this->memberdata as $key=>$member){
echo $key.':'.$member.'<br>';
}
}
}
}
$userobj = new User();
$userobj->set_name('fdipzone');
$userobj->set_age(29);
$userobj->show();
$probj = new Profession();
$probj->set_profession('IT SERVICE');
$probj->set_price(2500);
$probj->show();
/*输出
name:fdipzone
age:29
profession:IT SERVICE
price:2500*/
?>
利用__call
方法实现了扩展性极大的setter/getter
<?php
class Member{
protected static $memberdata = array();
public static function __callStatic($func, $arguments){
list($type, $name) = explode('_', $func);
if(!in_array($type, array('set','get')) || $name==''){
return '';
}
$feature = get_called_class();
switch($type){
case 'set':
self::$memberdata[$feature][$name] = $arguments[0];
break;
case 'get':
return isset(self::$memberdata[$feature][$name])? self::$memberdata[$feature][$name] : '';
break;
default:
}
}
}
class User extends Member{
public static function show(){
$feature = get_called_class();
if(self::$memberdata[$feature]){
foreach(self::$memberdata[$feature] as $key=>$member){
echo $key.':'.$member.'<br>';
}
}
}
}
class Profession extends Member{
public static function show(){
$feature = get_called_class();
if(self::$memberdata[$feature]){
foreach(self::$memberdata[$feature] as $key=>$member){
echo $key.':'.$member.'<br>';
}
}
}
}
User::set_name('fdipzone');
User::set_age(29);
User::show();
Profession::set_profession('IT SERVICE');
Profession::set_price(2500);
Profession::show();
?>
同__call
__callStatic
只是静态方法的实现版本,值得注意的是get_called_class()
方法是获取子类的类名。
静态方法中要用self::
调用方法和变量,在实例对象中要用$this->
。