## 魔术方法 :__call( )实例详解
#### 1. 功能:当调用的方法不存在或权限不足时自动触发该方法。
>[info] 框架中每个类几乎都有这个魔术方法,很实用也很简单,直接上实例讲解。
#### 2. 实例:
>[warning] 几乎每一步都有注释,如果感到陌生,请参阅《PHP官方手册》。
~~~
<?php
//创建父类:Member
class Member{
//创建受保护属性:数组
protected $memberdata = array();
//当调用的方法不存在或权限不足时,会自动调用__call方法
public static function __call($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 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 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方法,于是自动触发父类__call()方法
//父类Member中的__call($func,$arguments)是系统魔术方法
//在__call方法中,方法名set_name转换为变量$type和$name
//并根据$type,完成属性的动态赋值或读取操作
//set_name(),set_age()分别完成了对$memberdata[$feature]属性的动态赋值操作
$user = new User();
$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 = new Profession();
$profession -> set_lession('模型');
$profession -> set_teacher('理达课堂');
$profession -> show();
~~~
* 运行结果:
~~~
name:ThinkPHP
age:10
lession:模型
teacher:理达课堂
~~~
#### 4. 总结:
>[success] 当调用不存在的方法,或者越权调用某个方法,__call( )方法提供了一种容错机制,可以让我们更加灵活的使用面向对象编程,带来的好处。
- 前言[随时更新]
- 开发环境
- 1.Mac环境
- 2.windows环境
- 模型对象
- 1.创建模型对象
- 2.模型初始化
- 数据对象
- 1.定义数据对象
- 2.创建数据对象
- 1.data方法
- 2.setAttr方法
- 3.__set方法
- 4.查询数据对象
- 1.getData方法
- 2.getAttr方法
- 3.__get方法
- OOP难点总结
- 1.get_class( )实例讲解
- 2.get_called_class( )实例讲解
- 3.__call( )实例讲解
- 3.__callStatic( )实例讲解
- 4.call_user_func_array函数[重点]
- 5.普通方法与静态方法
- 6.在Model源码中的应用
- 7.new static 延迟静态绑定
- PHP标准化规范
- 查询数据
- 1.获取单条:get静态方法
- 2.获取单条:对象查询
- 3.获取多条:all静态方法
- 4.获取多条:对象查询
- 5.获取字段值:value方法
- 6.获取列值:column方法
- 7.动态查询:getBy字段名
- 8.助手函数:model查询
- 9.加载器:Loader类查询
- 10.数据库与模型查询对比
- 新增数据
- 1.sava方法
- 2.savaAll方法
- 3.create静态方法
- 4.insert静态调用
- 更新数据
- 1.单条更新:save方法
- 2.批量更新:saveAll方法
- 3.静态更新:update方法
- 4.查询类Query直接更新
- 5. 闭包更新
- 删除数据
- 1.删除当前记录:delete
- 2.静态条件删除:destory
- 获取器
- 1.模型方法:set属性Attr
- 修改器
- 1.set属性Attr
- 时间戳
- 1.MySQL中日期类型复习
- 2.时间戳功能详解
- 软删除[重点]
- 1.traits详解[选学内容]
- 2.SoftDelet类源码分析
- 3. delete实例删除
- 4.destroy条件删除
- 5.restore恢复数据
- 类型转换
- 1. 规则设置
- 2. 实例演示
- 查询范围
- 1. 基本概念
- 2.实例演示