魔术方法:
是指某些情况下,会自动调用的方法,称为魔术方法
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));

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

PHP中的常用魔术方法的更多相关文章

  1. php中的常用魔术方法总结

    以下是对php中的常用魔术方法进行了详细的总结介绍,需要的朋友可以过来参考下 常用的魔术方法有:__Tostring () __Call() __autoLoad() __ clone() __GET ...

  2. Python中的常用魔术方法介绍

    1.__init__ 初始化魔术方法 触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中) 参数:至少有一个self,接收对象 返回值:无 作用:初始化对象的成员 注意:使用该方式初 ...

  3. php中常用魔术方法的举例

    魔术方法是php面向对象特有的功能,并且有时候能实现意想不到的效果,包括前面提到的构造函数.析构函数.还有__clone函数,另外再简单的介绍几个: 1.__toSring和__invoke clas ...

  4. PHP 中 16 个魔术方法详解

    PHP 中 16 个魔术方法详解   前言 PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),这些方法在PHP中充当了举足轻重的作用. 魔术方法包括: __constru ...

  5. python常用魔术方法概览

    构造和初始化 __init__(self, args) 构造函数 __new__(cls) 传入的是类实例 __del__(self) 析构函数,调用 del cls 时会被调用 属性访问控制 __g ...

  6. c#中的常用ToString()方法总结

    c#中的常用ToString()方法总结 对于int,double等的tostring: C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToStri ...

  7. 问题:C# ToString("P");结果:c#中的常用ToString()方法总结

    c#中的常用ToString()方法总结   很多类都重写了ToString方法, 导致很多类的tostring到底执行了什么,有哪些参数,都不清楚 对于int,double等的tostring: C ...

  8. [Python3 填坑] 014 类的常用魔术方法举例

    目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 __init__() 2.2 __new__() 2.3 __call__() 2.4 __str__() 2.5 __repr__() ...

  9. Python 基础之面向对象之常用魔术方法

    一.__init__魔术属性 触发时机:实例化对象,初始化的时候触发功能:为对象添加成员,用来做初始化的参数:参数不固定,至少一个self参数返回值:无 1.基本用法 #例:class MyClass ...

随机推荐

  1. iOS开发——UI基础-懒加载,plist文件,字典转模型,自定义view

    一.懒加载 只有使用到了商品数组才会创建数组 保证数组只会被创建一次 只要能够保证数组在使用时才创建, 并且只会创建一次, 那么我们就称之为懒加载 lazy - (void)viewDidLoad 控 ...

  2. OpenCV中对图像进行二值化的关键函数——cvThreshold()。

    函数功能:采用Canny方法对图像进行边缘检测 函数原型: void cvThreshold( const CvArr* src, CvArr* dst, double threshold, doub ...

  3. Android 解析JSON格式数据

    比起XML,JSON主要优势在于它的体积更小,在网络上传输的时候可以更省流量.但缺点在于,它的语义性较差,显示不如XML直观. JSON格式 :  { "name_A" : &qu ...

  4. hdu1054 树形dp&&二分图

    B - Strategic Game Time Limit:10000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  5. ssh免密码登入

    通常做许多事情(git puh/脚本等等),不停输入密码是件很不愉快的事情,破解如下: http://www.linuxproblem.org/art_9.html 1. 生成rsa密钥 ssh-ke ...

  6. POCO浅探

    POCO作用类似于POJO.POJO的内在含义是指那些从来没有任何类继承.也没有实现任何接口,更是没有被其他框架侵入的JAVA对象.POCO的含义与此是一致的.POJO的意义就在于它的简单灵活性,能够 ...

  7. (转) Docker swarm 之介绍与使用

    今天,在站内看到一篇关于Docker Swarm 的文章,非常好,在这里转过来,方便日后查阅 :) 原贴链接: http://www.cnblogs.com/rio2607/p/4445968.htm ...

  8. js中val()和value的区别

    val()是在有jQuery插件的时候才能用,value是在没有jQuery插件的情况下也能用.val()是jQuery根据原生JS里面的value写出来的函数 $(this).val(); 有四个重 ...

  9. 如何在maven中添加本地jar包

    mvn install:install-file -DgroupId=mytest-DartifactId=test-Dversion=1.1 -Dpackaging=jar -Dfile=d:\te ...

  10. MySQL表中数据的迁移

    INSERT INTO `crm_attachment`(OPERATOR_ID,ATTACHMENT_ID,TYPE ) SELECT APPLICATION_ID ,ATTACHMENT_ID,' ...