魔术方法:
是指某些情况下,会自动调用的方法,称为魔术方法
php面向对象中,提供了这几个魔术方法,他们的特点都是
以双下划线__开头的
__construct() 构造方法
__destruct() 析构方法
__clone()
克隆方法
当对象被格隆时,将会自动调用
克隆方法
当对象被格隆时,将会自动调用
例:
class Human{
public $age=22;
public function __clone(){
echo
"有人克隆我!假冒";
//当对象被格隆时,将会自动调用
"有人克隆我!假冒";
//当对象被格隆时,将会自动调用
}
}
$lisi=new Human();
$zhangsan=clone $lisi;
//克隆$lisi对象
//输出
有人格隆我!假冒
//克隆$lisi对象
//输出
有人格隆我!假冒
//接下来讲6个,在项目中,尤其是自己想写框架时,很实用的几个函数
__call()
__callstatic()
__get()
__set()
__isset()
__unset()
====================
__get
例:
class Human{
private
$money='30两';
$money='30两';
protected $age=23;
public
$name='lisi';
$name='lisi';
public function
__get($p){
__get($p){
echo
"你想访问我的",$p,'属性';
"你想访问我的",$p,'属性';
}
}
$lisi=new Human();
echo $lisi->name;
//输出 lisi
//输出 lisi
echo $lisi->age;
//输出
你想访问我的age属性
//输出
你想访问我的age属性
echo $lisi->friend;
//输出
你想访问我的friend属性
当调用未定义的属性时,也会自动调用__get方法
//输出
你想访问我的friend属性
当调用未定义的属性时,也会自动调用__get方法
可以总结出
当我们调用一个权限上不允许调用的属性时和不存在的属性时,
__get魔术方法会自动调用,并且自动传参,参数值是
你调用时的属性名
你调用时的属性名
流程:
$lisi->age-无权-->__get('age');
$lisi->friend---没有此属性->__get('friend');
生活中,你帮别人看守小卖店
买牙刷-->好,给你牙刷
买毛巾-->好,给你毛巾
这个pos机挺好--->(pos是商店的工具,私有的,不卖,你无权买),但是
我们用__get方法,就有一个友好的处理机会。
不然系统会直接报错,甚至fatal error,通过__get,我们就能自己定义访问时,的处理行为。
__set
接上面
$lisi->aaa=111;
$lisi->bbb=222;
//调用了不存在的属性并赋值
这两个居然加到了对象里
//调用了不存在的属性并赋值
这两个居然加到了对象里
print_r($lisi);
竟然给加上了.
其实,对象就是一个属性集,在js中更明显.
如果这么随便就能加上了属性,导致这个对象属性过多,不好管理
class Stu{
private
$money="30两";
$money="30两";
protected $age=23;
public $name='Hmm';
public function
__set($a,$b){
__set($a,$b){
echo '你想设置我的',$a,'属性';
echo '且值是',$b;
}
}
$hmm=new Stu();
$hmm->aaa=111;
//输出 你想设置我的aaa属性
且值是111
//输出 你想设置我的aaa属性
且值是111
print_r($hmm);
$hmm->money="40两";
//输出
你想设置我的money属性 且值是40两
//输出
你想设置我的money属性 且值是40两
$hmm->age='28';
//输出
你想设置我的age属性 且值是28
//输出
你想设置我的age属性 且值是28
$hmm->name='韩美美'; //成功把
$name属性的值改了
$name属性的值改了
print_r($hmm);
如上,总结出
当为无权操作的属性赋值时,或不存在的属性赋值时,__set()自动调用且自动传2个参数 就是你调用时的
属性 属性值
属性 属性值
例:
$hmm->age=28 --无权->__set('age',28);
例:
class Dog{
public $leg=4;
protected
$bone="猪腿骨";
$bone="猪腿骨";
public function
__isset($p){
__isset($p){
echo
'你想判断我的',$p,'属性存不存在';
'你想判断我的',$p,'属性存不存在';
return 1;
//这里return
1 会影响 isset的判断为真了
}
public function __unset($p){
echo
'你想去掉我的',$p;
'你想去掉我的',$p;
}
}
$hua=new Dog();
if(isset($hua->leg)){
//isset是语法结构判断变量是否存在
//isset是语法结构判断变量是否存在
echo $hua->leg;
//输出
4
//输出
4
}
if(isset($hua->tail)){ //调用了未定义的属性
触发了 __isset魔术方法
输出
你想判断我的tail属性存不存在
触发了 __isset魔术方法
输出
你想判断我的tail属性存不存在
echo '有tail属性';
//输出 有tail属性
就是因为
__isset里面return 了 真 才会导致判断失误
//输出 有tail属性
就是因为
__isset里面return 了 真 才会导致判断失误
}else{
echo
"没有tail属性";
"没有tail属性";
}
__isset()方法
当
isset判断对象不可见的属性时(protected/private/不存在的属性)
isset判断对象不可见的属性时(protected/private/不存在的属性)
都会引发 __isset()来执行
问:isset($obj->xyz)属性,为真
能说明 类声明了一个xyz属性吗?
答:不一定
unset($hua->leg); //把$leg变量删掉了
unset($hua->tail); //调用一个不存在的属性
会触发 __unset魔术方法 输出
你想去掉我的tail
会触发 __unset魔术方法 输出
你想去掉我的tail
unset($hua->bone); //调用了一个受保护的属性 也会触发
__unset魔术方法
__unset魔术方法
__unset()方法
当用 unset销毁对象的不可见属性时(protected/private/不存在的属性)时
会引发 __unset()魔术方法;
例:
unsert($hua->tail)---没有tail属性--->触发
__unsert('tail');
__unsert('tail');
例:
class Human{
public function
hello(){
hello(){
echo
'hello';
'hello';
}
private function
t(){
t(){
echo "你";
}
public function
__call($metch,$argu){
__call($metch,$argu){
echo '你想调用一个我不存在或无权操作的方法',$metch,'
';
echo '你调用时还传了参数';
print_r($argu);
}
}
$lisi=new Human();
$lisi->hello; //输出 hello
$lisi->say();
//调用未定义的方法会触发 __call魔术方法
//调用未定义的方法会触发 __call魔术方法
//输出
你想调用一个我不存在或无权操作的方法say
你调用时还传了参数
Array ()
$lisi->t(1,2,3);
//调用私有的方法 也会触发 __call 魔术方法
//调用私有的方法 也会触发 __call 魔术方法
//输出
你想调用一个我不存在或无权操作的方法t 你调用时还传了参数
Array ([0]=>1 [1]=>2 [2]=>3)
$lisi->say(); 没有say方法----》触发 __call('say',array());
$lisi->t(1,2,3); 无权操作t方法----》触发
__call('t',array(1,2,3));
__call('t',array(1,2,3));
当调用一个未定义或无权操作的方法会触发 __call魔术方法
第一个参数是 你调用时的方法名
第二个参数是 一个数组
你调用方法时没带参数就是一个空数组
带了参数就是参数组成的数组
你调用方法时没带参数就是一个空数组
带了参数就是参数组成的数组
看如上用法
例:
class Human{
static protected function qq(){
echo '是';
}
static public function
__callStatic($a,$b){
__callStatic($a,$b){
echo
"你想调用一个不存在或无权调用的静态方法",$a,"
";
"你想调用一个不存在或无权调用的静态方法",$a,"
";
echo '你想调用时还传了参数
';
';
print_r($b);
}
}
$lisi=new Human();
Human::say('痛苦','悲哀','爱'); //输出
你想调用一个不存在或无权调用的静态方法say
你想调用一个不存在或无权调用的静态方法say
//你想调用时还传了参数
Array ( [0] => 痛苦 [1] => 悲哀 [2] => 爱
)
Human::qq();
//输出
你想调用一个不存在或无权调用的静态方法qq
//输出
你想调用一个不存在或无权调用的静态方法qq
// 你想调用时还传了参数 Array (
)
__callStatic 是调用不可见或无权操作的静态方法时,会自动调用。
声明__callStatic 注意要带 static
声明__callStatic 注意要带 static
注意 静态调用不可见或无权操作的静态方法的时候才会触发此
__callStatic 魔术方法
__callStatic 魔术方法
例:
Human::say(1,2,3)--没有say方法----触发
__callStatic(‘say’,array(1,2,3));
__callStatic(‘say’,array(1,2,3));
第一个参数是 你调用时的方法名
第二个参数是 一个数组
你调用方法时没带参数就是一个空数组
带了参数就是参数组成的数组
你调用方法时没带参数就是一个空数组
带了参数就是参数组成的数组