zoukankan      html  css  js  c++  java
  • 15个魔术方法的总结

     PHP5中魔术方法函数有哪几个,请举例说明各自的用法 

     __wakeup   __construct, __destruct __call,__get, __set, __isset, __unset __sleep, 

    __toString, __set_state, __clone __autoload 

    1.__autoload() 类文件自动加载函数

    这个魔术方法是用来自动加载程序所用到类文件的PHP源文件,这样就避免了我们一个一个自动去require或者include了,这个函数会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类,但是我最近看过一篇文章,上面说__autoload()的效率不是很高。以下是示例代码:

    1. <?php  
    2. 功能:在当前页使用类时自动加载该类的文件  
    3. 参数$className  为类的名称 可自定义  
    4. */  
    5. function __autoload($className){  
    6. $className=strtolower($className);//最好加上这一步,因为类首字母大写,某些系统区分文件名的大小写  
    7. require("$className.class.php");//加载类文件  One.class.php Two.class.php与本文件在同一目录下  
    8. echo '------------------------------<br>';//作为调用时的标记来测试  
    9. }  
    10. //以下两个类均未在本文件中定义  
    11. $o=new One();//使用One类,对其初始化  
    12. $t=new Two();//使用Two类,对其初始化  
    13. ?>  


    注意这个函数如果需要正常加载,需要将文件名设置成类名(推荐小写).class.php等类名和文件名有某种关联才可以,另外如果这个函数出现异常不能被Catch捕获,将会显示Fatal Error


    2.__construct() 构造函数

    在C#和PHP4中构造函数的函数名都是与类名相同,当然PHP5也支持这样(如果找不到__construct方法后会找函数名与类名相同的作为构造函数),之所以这样写的好处是如果我们想更改类的名字,我们就只改类名就可以,不用在更改构造函数的函数名,同时从某种程度上减少了我们出错的概率,示例代码还是简单写一下吧!

    1. <?php  
    2. class PcYoYo{  
    3. private $url;  
    4. function __construct($url){  
    5. $this->url=$url;  
    6. }  
    7. }  
    8. ?>  


    3.__destruct()  析构函数

    __destruct 析构方法,PHP将在对象被销毁前(即从内存中清除前)调用这个方法

    默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源.

    析构函数允许你在使用一个对象之后执行任意代码来清除内存.

    当PHP决定你的脚本不再与对象相关时,析构函数将被调用.

    在一个函数的命名空间内,这会发生在函数return的时候.

    对于全局变量,这发生于脚本结束的时候.如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值.通常将变量赋值勤为NULL或者调用unset.


    4.__call() 当所调用的成员方法不存在(或者没有权限)该类时调用,用于对错误后做一些操作或者提示信息

    1. <?php  
    2. //初始化一个类   
    3. class Person{  
    4. private $name;  
    5. private $age;  
    6. private $sex;  
    7. function walk($hour,$minute){  
    8. echo "$hour :$minute We will walk<br>";  
    9. }  
    10. function run(){  
    11. }  
    12. //使用魔术方法__call  
    13. /***** 
    14. 功能:在对象调用类中不存在的函数时自动调用,进行一些操作 
    15. 参数:$proName 所调用函数名称  $args 参数数组  $proName ,$args  为自定义的形参可符合自己风格变动,但是这两个参数的意义是固定的 
    16. *****/  
    17. function __call($proName,$args){  
    18. echo "The $proName doesn't exist! the parameters are";  
    19. print_r($args);  
    20. echo '<br>';  
    21. }  
    22. }// the end of class  
    23. //实例化一个对象  
    24. $p=new Person();  
    25. //调用Person类中存在的方法  
    26. $p->walk(5,39);  
    27. //调用Person类中不存在的方法  
    28. $p->work();//如果没有使用魔术方法__call,则程序发生错误,错误信息Fatal error: Call to undefined method Person::work() in D:/phpnow/htdocs/holiday/magic__call.php on line 29  
    29. //如果使用了魔术方法__call,则在对象调用类中不存在的函数时,__call被自动调用,用来执行某些操作。  
    30. ?>  


    5.__clone()

    该函数在对象克隆时自动调用,其作用是对克隆的副本做一些初始化操作

    1. <?php  
    2. //初始化一个类  
    3. class Computer{  
    4. //  
    5. public $cpu='intel';  
    6. private $monitor;  
    7. private $keyboard;  
    8. //设置魔术方法__clone()函数  
    9. function __clone(){//如果不设置这个魔术方法那么克隆出来的就是一模一样的,__clone函数和类的构造函数类似都是做一些初始化操作  
    10. $this->cpu='AMD';//$this指的是新创建的克隆对象  
    11. }  
    12. //设置析构函数,用来比较=和clone的区别  
    13. function __destruct(){  
    14. echo '*************************************<br>';  
    15. }  
    16. }// the end of the class  
    17. //实例化一个对象  
    18. $c1=new Computer();  
    19. //使用引用的方法在添加一个引用,因为对象的引用是存放在内存中的栈内存中,如果按指针的说法,那么这样做就是在内存中有创建了一个指针指向$c1指向的对象  
    20. //我们可以通过条用析构函数判断出来这样不是复制了对象  
    21. $c2=$c1;  
    22. //使用clone方法克隆一个对象  
    23. $c3=clone $c1;  
    24. //输出两者的信息比较  
    25. echo $c1->cpu,'<br>';  
    26. echo $c3->cpu,'<br>';  
    27. ?>  


    6.__get() 当所对象所调用的成员属性未声明或者级别为private或者protected等时,我们可以在这个函数里进行自己的一些操作

    1. <?php  
    2. class Person{  
    3. private $name;  
    4. public $nation;  
    5. function __get($para){//必须有一个参数  
    6. echo $para.'不存在';  
    7. }  
    8. }  
    9. $p=new Person();  
    10. $name=$p->name;//call the __get function  
    11. $nation=$p->nation;//never call the __get function  
    12. ?>  


    7.__set() 当所对未声明或者级别为private或者protected等进行赋值时调用此函数,我们可以在这个函数里进行自己的一些操作

    1. <?php  
    2. class Pc{  
    3. private $key;  
    4. function __set($key,$value){//必须有两个参数一个是成员属性,另一个是值  
    5. echo '对'.$key.'赋值为'.$value.'失败';  
    6. }  
    7. }  
    8. $p=new Pc();  
    9. $p->key=123;  
    10. ?>  


    8.__isset() 当对一个未声明或者访问级别受限的成员属性调用isset函数时调用此函数,共用户做一些操作


    9.__unset() 当对一个未声明或者访问级别受限的成员属性调用unset函数时调用此函数,共用户做一些操作


    10.__toString()函数 该函数在将对象引用作为字符串操作时自动调用,返回一个字符串

    1. <?php  
    2. //初始化一个类  
    3. class Phone{  
    4. //类的成员属性  
    5. private $brand;  
    6. private $model;  
    7. private $price;  
    8. //构造函数  
    9. function __construct($pbrand,$pmodel,$pprice){  
    10. $this->brand=$pbrand;  
    11. $this->model=$pmodel;  
    12. $this->price=$pprice;  
    13. }  
    14. //魔术方法__toString()  
    15. function __toString(){  
    16. return "{$this->brand} {$this->model} {$this->price}";//可以自定义操作但必须要返回一个字符串结果   
    17. }  
    18. }// the end of class  
    19. //实例化一个对象  
    20. $p=new Phone('Google','Nexus One',4200);  
    21. //如果没有在类中使用__toString函数则报错Catchable fatal error: Object of class Phone could not be converted to string  
    22. //如果在类中使用了__toString函数,则把对象当字符串输出时,执行__toString函数操作  
    23. echo $p;  
    24. ?>  


    11.__sleep()函数 该函数是在序列化时自动调用的,序列化这里可以理解成将信息写如文件中更长久保存

    1. <?php  
    2. //初始化一个类  
    3. class User{  
    4. //类的成员属性  
    5. private $name;  
    6. private $age;  
    7. private $sex;  
    8. //构造函数  
    9. function __construct($pname,$page,$psex){  
    10. $this->name=$pname;  
    11. $this->age=$page;  
    12. $this->sex=$psex;  
    13. }  
    14. //设置魔术方法__sleep()  
    15. /* 
    16. 功能:返回一个数组,选择是全部序列化还是部分成员属性序列化,如果没有该函数就表示全部序列化 
    17. 在序列化的时候自动调用这个方法 
    18. */  
    19. function __sleep(){  
    20. return array('name');   //返回一个只序列化name属性的数组  
    21. }  
    22. }//the end of the class  
    23. $u=new User('Androidyue',22,'Man');//实例化一个对象  
    24. file_put_contents('notepad1.txt',serialize($u));//序列化$u对象并且将信息存放在notepad1.txt文件中  
    25.                                                                                                                              
    26. ?>  


    12.__wakeup()函数 该魔术方法在反序列化的时候自动调用,为反序列化生成的对象做一些初始化操作

    1. <?php  
    2. //初始化一个类  
    3. class User{  
    4. //类的成员属性  
    5. private $name;  
    6. private $age;  
    7. private $sex;  
    8. //构造函数  
    9. function __construct($pname,$page,$psex){  
    10. $this->name=$pname;  
    11. $this->age=$page;  
    12. $this->sex=$psex;  
    13. }  
    14. //设置魔术方法__sleep()  
    15. /* 
    16. 功能:返回一个数组,选择是全部序列化还是部分成员属性序列化,如果没有该函数就表示全部序列化 
    17. 在序列化的时候自动调用这个方法 
    18. */  
    19. function __sleep(){  
    20. return array('name');   //返回一个只序列化name属性的数组  
    21. }  
    22. function __wakeup(){  
    23. $this->name='Yue';  
    24. //$this->age=23;  
    25. }  
    26. }//the end of the class  
    27. $u=new User('Androidyue',22,'Man');//实例化一个对象  
    28. //file_put_contents('notepad1.txt',serialize($u));//序列化$u对象并且将信息存放在notepad1.txt文件中  
    29. //获取序列化的文件信息  
    30. $str=file_get_contents('notepad1.txt');  
    31. //对文件进行反序列化  
    32. $uu=unserialize($str);  
    33. //输出对象的信息  
    34. var_dump($uu);//结果:object(User)#2 (3) { ["name:private"]=> string(3) "Yue" ["age:private"]=> NULL ["sex:private"]=> NULL }  
    35. ?>  


    13.当调用var_export()时,这个静态 方法会被调用(自PHP 5.1.0起有效)。本方法的唯一参数是一个数组,其中包含按array(’property’ => value, …)格式排列的类属性。

    1. <?php  
    2. class Author{  
    3.    public $name;  
    4.    public $works;  
    5.   public static function __set_state($arr){  
    6.      $a=new Author();  
    7.      $a->name=$arr['name'];  
    8.      $a->works=$arr['works'];  
    9.         return $a ;  
    10.    }  
    11. }  
    12. $a = new Author();  
    13. //对成员属性赋值,当然通常我们不建议这样赋值(即将成员属性设置成public直接赋值)  
    14. $a->name='Androidyue';  
    15. $a->works='PHP codes';  
    16. //执行一个语句  
    17. eval('$b = ' . var_export($a, true) . ';');//这样是$b 为对象类型  
    18. //$b=var_export($a,true);//这样会是$b 为字符串  
    19. var_dump($b);  
    20. ?>  


    14.__invoke

    当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用。

    PHP5.3.0以上版本有效,我的php版本为5.2.12,暂不支持,因此无法演示。


    15.__callStatic

    它的工作方式类似于 __call() 魔术方法,__callStatic() 是为了处理静态方法调用,

    PHP5.3.0以上版本有效  我的php版本为5.2.12,暂不支持,因此无法演示。

    PHP 确实加强了对 __callStatic() 方法的定义;所作用的函数必须是公共的,并且必须被声明为静态的。同样,__call() 魔术方法必须被定义为公共的,所有其他魔术方法都必须如此

  • 相关阅读:
    转载:Python十分钟入门
    Think Python: How to Think Like a Computer Scientist
    LeetCode(34):搜索范围
    LeetCode(33):搜索旋转排序数组
    LeetCode(32):最长有效括号
    LeetCode(31): 下一个排列
    LeetCode(30):与所有单词相关联的字串
    LeetCode(29): 两数相除
    LeetCode(28): 实现strStr()
    LeetCode(27): 移除元素
  • 原文地址:https://www.cnblogs.com/ghjbk/p/6934140.html
Copyright © 2011-2022 走看看