php面相对象的魔术方法中文说明与例子

在 PHP 中以两个下划线开头的方法,__construct(),__destruct (),__call(),__callStatic(),__get(),__set(),__isset(),__unset (),__sleep(),__wakeup() 等,被称为"魔术方法"(Magic methods).

集合涵义

在PHP中以两个下划线开头的方法,__construct(), __destruct (), __call(), __callStatic(),__get(), __set(), __isset(), __unset (), __sleep(), __wakeup(), __toString(), __set_state,() __clone() __autoload()等,被称为"魔术方法"(Magic methods)。如果希望PHP调用这些魔术方法,首先必须的类中定义,否则PHP不会执行未创建的魔术方法。[1]

注意:PHP 将所有以 __(两个下划线)开头的类方法保留为魔术方法,所以在定义类方法时,除了上述魔术方法,建议不要以 __ 为前缀.

魔术方法中文说明

PHP面向对象有哪些魔术方法,每个魔术方法如何如何,请写个测试类并运行

_construct($argv1,$argv2,...)

功能:类的构造方法,作用就是初始化对象

参数:任意多个,任意类型

返回值:无

__destruct()

功能:类的析构方法,对象被销毁时被调用的,作用是释放内存

参数:无

返回值:无

__get($name)

功能:当程序试图调用一个未定义或者不可见的成员变量的时候就会自动调用该方法,这个时候程序试图调用*的成员变量的返回值是该方法的返回值;

参数:$name为试图调用的成员变量的名称,这个参数的传递是PHP自动完成的;

返回值:类型(不确定)注意该方法可以设置成私有的(构造方法不要设置成私有的)。

__set($name,$value)魔术方法

功能:当程序试图给一个未定义或者不可见的成员变量赋值的时候就会自动调用该方法;

参数:$name,$value分别表示试图赋值的成员变量名称和成员变量的值,这两个参数的传递是PHP自动完成的;

返回值:这个方法不会返回值 注意该方法可以设置成私有的(构造方法不要设置成私有的)。

__isset($name)

功能:当用isset($name)检测一个私有的成员变量的时候就会自动调用该方法,这个时候isset($name)的返回值就为该方法的返回值经过转化的布尔值(<除“0”>非空的字符串,非零,true,有单元的数组将会转化为true;0,"0",空*字符串,NULL,没有单元的数组将会转化为false);

参数:$name为试图检测的成员变量的名称,这个参数的传递是PHP自动完成的;

返回值:类型(不确定)注意该方法可以设置成私有的(构造方法不要设置成私有的),当用isset()函数检测的是公有的成员变量的时候可以直接检测,如果没有__isset()方法而直接检测私有成员会得到不准确的结果即isset()会始终返回false;

_unset($name)

功能:当用unset($name)撤销一个私有的成员变量的时候就会自动调用该方法;

参数:$name为试图撤销的成员变量的名称,这个参数的传递是PHP自动完成的;

返回值:不能返回值,强制返回值将会出错,当用unset()函数撤销的是公有的成员变量的时候可以直接撤销,如果没有__unset()方法而直接撤销私有成员不会成功;

__toString()

功能:当程度试图输出一个对象类型的变量的时候PHP会自动调用该方法;

参数:没有参数,如果有会提示出错;

返回值:字符型(该方法必须通过return返回一个字符串);

__clone()

功能:在用clone关键字克隆一个对象的时候PHP会自动调用这个方法,是为了给克隆出来的对象增添自己的属性和方法;

参数:不用传递参数;

返回值:不用返回值;

_call($name,$argument)

功能:当程序试图调用一个不存在的成员方法的时候会自动调用该方法;

参数:PHP将自动将调用的不存在的方法名传递给$name,不存在的方法中的参数整合为一个数组传递给*$argument;

返回值:不用返回值;

_sleep()

功能:使用serialize()函数时,如果实例化的对象中包含__sleep()方法,则会先执行__sleep()方法,该方法可以清除对象并返回该对象中所有变量的数组。使用__sleep()方法的目的是关闭对象可能具有的数据库连接等类似的善后工作

参数:无需要传递参数

返回值:数组类型(Array)该对象中所有变量的数组

__wakeup()

功能:使用unserialize()函数重新还原一个被serialize()函数序列化的对象,__wakeup()方法则是恢复序列化中可能丢失的数据库连接及相关工作

参数:无需要传递参数

返回值:----------------------------

__set_state($arr)

功能:可以通过var_export()来访问类的静态方法__set_state(),该方法必须是静态的且必须返回一个对象

参数:$arr为一个数组

返回值:为一个对象

__autoload($class_name)

功能:在指定的路径下自动查找并导入实例化需要使用的类

参数:$class_name为类名

返回值:*__callStatic($name,$argument)

功能:当程序试图在静态方法中调用一个未定义或者不可见的成员方法的时候会自动调用该方法;

参数:PHP将自动将调用的不存在的方法名传递给$name,不存在的方法中的参数整合为一个数组传递给$argument;

返回值:不用返回值;

注意:PHP5.3以上的版本支持该魔术方法

注意:__classStatic()方法必须被申明为public并且为static,否则会产生一个warning错误.

__invoke($x,$y,...)

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

参数:以函数调用方法调用一个对象时传递的任意多个参数

返回值:不确定*

注意:PHP5.3以上的版本支持该魔术方法

魔术方法例子,代码如下:

  1. <?php
  2. class XuDianYang{
  3. public $sex;
  4. public $age;
  5. private $girlfriend='xx';
  6. public function __construct($sex,$age){
  7. $this->sex=$sex;
  8. $this->age=$age;
  9. }
  10. public function __get($name){
  11. echo __class__."::".$name."不存在或者不可见";
  12. }
  13. public function __set($name,$value){
  14. echo __class__."::".$name."由于不在在或者不可见,赋值失败";
  15. }
  16. public function __isset($name){
  17. if(isset($this->$name)){
  18. echo 1;
  19. }else{
  20. echo 0;
  21. }
  22. }
  23. public function __unset($name){
  24. unset($this->$name);
  25. }
  26. public function __toString(){
  27. return __class__;
  28. }
  29. public function __clone(){
  30. $this->sex='女';
  31. }
  32. public function __call($name,$argument){
  33. echo "方法".__class__."::".$name."不存在";
  34. }
  35. public function __sleep(){
  36. echo "I'm sleeping";
  37. foreach($this as $key=>$value){
  38. $arr[]=$key;
  39. }
  40. return $arr;
  41. }
  42. public function __wakeup(){
  43. echo "I wake up";
  44. }
  45. public function __set_state($arr){
  46. $obj=new CheShi();
  47. $obj->var1=$arr['sex'];
  48. $obj->var2=$arr['age'];
  49. return $obj;
  50. }
  51. }
  52. function __autoload($name){
  53. $class_path="./";
  54. include_once($class_path.$name.".class.php");
  55. }
  56. $xudianyang=new XuDianYang("男",21);
  57. echo "<br/>";
  58. //正常访问sex属性
  59. echo $xudianyang->sex;
  60. echo "<br/>";
  61. //由于不存在weight属性,将自动调用__get()方法
  62. echo $xudianyang->weight;
  63. echo "<br/>";
  64. //由于不可见(即私有),将自动调用__get()方法
  65. $xudianyang->girlfriend;
  66. echo "<br/>";
  67. //由于不存在,赋值失败,自动调用__set()方法
  68. $xudianyang->shengao="172cm";
  69. echo "<br/>";
  70. //检测sex属性是否存在,由于sex公有直接检测
  71. var_dump(isset($xudianyang->sex));
  72. echo "<br/>";
  73. //检测girlfriend是否存在,由于girlfriend私有,所以自动调用__isset()方法
  74. isset($xudianyang->girlfriend);
  75. echo "<br/>"; //开源软件:phpfensi.com
  76. //撤消girlfriend,由于girlfriend私有,所以自动调用__unset()方法
  77. //unset($xudianyang->girlfriend);
  78. isset($xudianyang->girlfriend);
  79. echo "<br/>";
  80. //直接输出一个对象,自动调用__toString()方法
  81. echo $xudianyang;
  82. echo "<br/>";
  83. $xu=clone $xudianyang;
  84. echo $xu->sex;
  85. echo "<br/>";
  86. //由于调用不存在的方法,自动调用__call()方法
  87. $xudianyang->walk();
  88. echo "<br/>";
  89. //序列化对象,自动调用__sleep()方法
  90. $a=serialize($xudianyang);
  91. echo "<br/>";
  92. echo "序列化的结果为:".$a;
  93. //反序列化对象,自动调用__wakeup()方法
  94. echo "<br/>";
  95. $b=unserialize($a);
  96. //反序列化的结果
  97. echo $b->sex;
  98. echo "<br/>";
  99. eval('$c='.var_export($xudianyang,true).";");
  100. echo $c->var1;
  101. ?>
  102. CheShi.class.php
  103. <?php
  104. class CheShi{
  105. public $var1;
  106. public $var2;
  107. }
  108. ?>