PHP中的常用魔术方法

魔术方法:
是指某些情况下,会自动调用的方法,称为魔术方法
php面向对象中,提供了这几个魔术方法,他们的特点都是
以双下划线__开头的

__construct()  构造方法
__destruct()   析构方法
__clone()    
 克隆方法    
   当对象被格隆时,将会自动调用

例:

class Human{

  public $age=22;

  public function __clone(){
     
   
      echo
"有人克隆我!假冒";    
   
 //当对象被格隆时,将会自动调用
  }
}
$lisi=new Human();
$zhangsan=clone $lisi;    
  //克隆$lisi对象  
   //输出  
有人格隆我!假冒

//接下来讲6个,在项目中,尤其是自己想写框架时,很实用的几个函数

__call()  
__callstatic()  
__get()
__set()
__isset()
__unset()


====================
__get

例:
 class Human{

   private
$money='30两';
   protected $age=23;
   public
$name='lisi';

   public function
__get($p){
     
 
      echo
"你想访问我的",$p,'属性';
   }
 
}

$lisi=new Human();

echo $lisi->name;    
  //输出  lisi
echo $lisi->age;    
 //输出    
你想访问我的age属性
echo $lisi->friend;    
 //输出    
你想访问我的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两";
   protected $age=23;
   public $name='Hmm';

   public function
__set($a,$b){

     
 echo '你想设置我的',$a,'属性';
     
 echo '且值是',$b;
   }

}


$hmm=new Stu();
$hmm->aaa=111;    
 //输出  你想设置我的aaa属性
 且值是111
print_r($hmm);
$hmm->money="40两";  
 //输出    
  你想设置我的money属性  且值是40两
$hmm->age='28';    
  //输出    
  你想设置我的age属性  且值是28
$hmm->name='韩美美';   //成功把
 $name属性的值改了
print_r($hmm);

如上,总结出
当为无权操作的属性赋值时,或不存在的属性赋值时,__set()自动调用且自动传2个参数 就是你调用时的
 属性  属性值
例:
$hmm->age=28 --无权->__set('age',28);


例:
 class Dog{

   public $leg=4;

   protected
$bone="猪腿骨";

   public function
__isset($p){
   
  
      echo
'你想判断我的',$p,'属性存不存在';

     
return 1;      
      //这里return
1 会影响 isset的判断为真了
   }
 public function __unset($p){

     echo
'你想去掉我的',$p;
  }
}


$hua=new Dog();

if(isset($hua->leg)){
 //isset是语法结构判断变量是否存在

    echo $hua->leg;
     //输出
  4
    
}


if(isset($hua->tail)){  //调用了未定义的属性
 触发了  __isset魔术方法
    输出  
  你想判断我的tail属性存不存在

    echo '有tail属性';
  //输出  有tail属性
      就是因为
__isset里面return 了 真  才会导致判断失误
  
}else{
     echo
"没有tail属性";
}


__isset()方法
当  
isset判断对象不可见的属性时(protected/private/不存在的属性)
都会引发 __isset()来执行


问:isset($obj->xyz)属性,为真
能说明 类声明了一个xyz属性吗?

答:不一定


unset($hua->leg); //把$leg变量删掉了
unset($hua->tail); //调用一个不存在的属性  
  会触发 __unset魔术方法  输出
 你想去掉我的tail
unset($hua->bone); //调用了一个受保护的属性   也会触发
 __unset魔术方法  

__unset()方法

当用 unset销毁对象的不可见属性时(protected/private/不存在的属性)时
会引发 __unset()魔术方法;

例:
 unsert($hua->tail)---没有tail属性--->触发
 __unsert('tail');



例:
 class Human{

   public function
hello(){

      echo
'hello';
   }

   private function
t(){
     
  echo "你";
   }

   public function
__call($metch,$argu){
     
 
     
 echo '你想调用一个我不存在或无权操作的方法',$metch,'

';
     
 echo '你调用时还传了参数';
     
 print_r($argu);
  }
}


$lisi=new Human();

$lisi->hello;   //输出 hello

$lisi->say();    
//调用未定义的方法会触发 __call魔术方法
     
     
      //输出
   你想调用一个我不存在或无权操作的方法say
   你调用时还传了参数  
Array ()

$lisi->t(1,2,3);    
//调用私有的方法 也会触发  __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魔术方法

第一个参数是 你调用时的方法名
第二个参数是  一个数组  
你调用方法时没带参数就是一个空数组    
带了参数就是参数组成的数组

看如上用法

例:  
class Human{

     
static protected function qq(){
  echo '是';
}

 static public function
__callStatic($a,$b){

    echo
"你想调用一个不存在或无权调用的静态方法",$a,"

";
echo '你想调用时还传了参数

';
print_r($b);
}
}
$lisi=new Human();

Human::say('痛苦','悲哀','爱');  //输出
 你想调用一个不存在或无权调用的静态方法say
     
     
     
     
     
   //你想调用时还传了参数
 Array ( [0] => 痛苦 [1] => 悲哀 [2] => 爱


Human::qq();    
     
     
  //输出
 你想调用一个不存在或无权调用的静态方法qq

     
     
     
     
     
  //  你想调用时还传了参数 Array (



 __callStatic 是调用不可见或无权操作的静态方法时,会自动调用。
 声明__callStatic 注意要带 static

注意  静态调用不可见或无权操作的静态方法的时候才会触发此
 __callStatic 魔术方法


例:
Human::say(1,2,3)--没有say方法----触发
__callStatic(‘say’,array(1,2,3));

第一个参数是 你调用时的方法名
第二个参数是  一个数组  
你调用方法时没带参数就是一个空数组    
带了参数就是参数组成的数组

上一篇:人脸识别批量生成一寸登记照 I.D. Photo


下一篇:python中字典常用的方法