• 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));

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

  • 相关阅读:
    众包实验:《分享上海》出书计划
    程序员笔试题(附答案)
    "客户管理系统"终于开发完毕,在这快乐元宵节里深吸一口气(图)
    SOA 初步阅读理解
    大型网站性能优化的通用方法(转)
    读《恒源祥彪悍广告是如何出炉的》后学习到的
    Asp.net生成静态页面最简单方法(源码)
    综合实习报告 写了一下午 图图图。。。。全是图
    程序员笔试题 将人民币金额转换成大写的金额
    扬太集团的网站也做完了,写篇日记算做总结吧
  • 原文地址:https://www.cnblogs.com/suiyuewuxin/p/5608483.html
Copyright © 2020-2023  润新知