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() 魔术方法必须被定义为公共的,所有其他魔术方法都必须如此

  • 相关阅读:
    leetcode Convert Sorted List to Binary Search Tree
    leetcode Convert Sorted Array to Binary Search Tree
    leetcode Binary Tree Level Order Traversal II
    leetcode Construct Binary Tree from Preorder and Inorder Traversal
    leetcode[105] Construct Binary Tree from Inorder and Postorder Traversal
    证明中序遍历O(n)
    leetcode Maximum Depth of Binary Tree
    限制 button 在 3 秒内不可重复点击
    HTML 和 CSS 画三角形和画多边行基本原理及实践
    在线前端 JS 或 HTML 或 CSS 编写 Demo 处 JSbin 与 jsFiddle 比较
  • 原文地址:https://www.cnblogs.com/ghjbk/p/6934140.html
Copyright © 2011-2022 走看看