## 魔术方法 :__callStatic( )实例详解 #### 1. 功能:当调用的静态方法不存在或权限不足时自动触发该方法。 >[info] 这个方法很重要,ThinkPHP5框架源码中几乎每个类都有这个方法。只有对这个方法熟悉,你才能完全了解框架的执行流程。 #### 2. 实例: >[warning] 每一关键步骤,都有详细注释,手把手,一定能学会 ~~~ <?php //创建父类:Member class Member{ //创建受保护静态属性:数组 protected static $memberdata = array(); //当调用的静态方法不存在或权限不足时,会自动调用__callStatic方法 public static function __callStatic($func, $arguments){ //explode():用'_'字符串分割为数组 //list():将数组元素转为对应的独立变量:$type,$name list($type, $name) = explode('_', $func); //如何$type字符串不在数组'set'和'get'中任何一个 //或者$name为空的话,则调用的静态方法名称不正确,直接返回'空'; if(!in_array($type, array('set','get')) || $name==''){ return ''; } //获取调用当前方法的类名 //即:当前方法静态绑定的类名: 如 User $feature = get_called_class(); //判断$type值 switch($type){ //如果$type = 'set',则是给属性$memeberdata赋值 case 'set': //将当前方法的参数数组的值$arguments[0] //赋给属性 $memberdata[$feature][$name]:注意是二维数组 //当前方法只有一个值:$arguments[0] self::$memberdata[$feature][$name] = $arguments[0]; break; //如果$type = 'get',则是获取属性$memeberdata的值 case 'get': //如果 self::$memberdata[$feature][$name]存在则返回该值,否则返回:空 return isset(self::$memberdata[$feature][$name])? self::$memberdata[$feature][$name] : ''; break; default: } } } //创建子类:User,继承自:Member类 class User extends Member{ //定义公共静态方法:show(),用来输出数据 public static function show(){ //获取调用当前方法的类名,如:User $feature = get_called_class(); //如果self::$memberdata[$feature]属性存在 if(self::$memberdata[$feature]){ //输出与当前类所对应的$memberdata[$feature]属性值 foreach(self::$memberdata[$feature] as $key=>$member){ echo $key.':'.$member.'<br>'; } } } } //创建子类:Profession,继承自:Member类 class Profession extends Member{ //定义公共静态方法:show(),用来输出数据 public static function show(){ //获取调用当前方法的类名,如:Profession $feature = get_called_class(); //如果self::$memberdata[$feature]属性存在 if(self::$memberdata[$feature]){ //输出与当前类所对应的$memberdata[$feature]属性值 foreach(self::$memberdata[$feature] as $key=>$member){ echo $key.':'.$member.'<br>'; } } } } //静态调用set_name(),set_age() //当前类User和父类中都没有set_name静态方法,于是自动触发父类__callStatic()方法 //父类Member中的__callStatic($func,$arguments)是系统魔术方法 //在__callStatic方法中,方法名set_name转换为变量$type和$name //并根据$type,完成属性的动态赋值或读取操作 //set_name(),set_age()分别完成了对$memberdata[$feature]属性的动态赋值操作 User::set_name('ThinkPHP'); User::set_age(10); User::show(); //静态调用set_profession(),set_price() //当前类User和父类中都没有set_name静态方法,于是自动触发父类__callStatic()方法 //父类Member中的__callStatic($func,$arguments)是系统魔术方法 //在__callStatic方法中,方法名set_name转换为变量$type和$name //并根据$type,完成属性的动态赋值或读取操作 //set_name(),set_age()分别完成了对$memberdata[$feature]属性的动态赋值操作 Profession::set_lession('模型'); Profession::set_teacher('理达课堂'); Profession::show(); ~~~ * 运行结果: ~~~ name:ThinkPHP age:10 lession:模型 teacher:理达课堂 ~~~ #### 4. 总结: >[success] 该方法与上节课的__call( )方法,有很多相似之外,请注意区分