图片.png
图片.png
系统调用的,不是你自己调用的,你只要把这个方法写出来之后在特定的时机系统就会为你自动调用,你只需要实现这个方法即可。
图片.png

__get

触发时机:对象在外部访问私有成员或者受保护属性时调用
该方法有一个参数:参数就是属性名

  1. <?php
  2. class Person
  3. {
  4. public $name='小明';
  5. protected $age=18;
  6. private $height=187;
  7. //当你在外部试图通过对象来访问受保护的或者私有的成员属性时,就会自动触发__get()
  8. public function __get($name)//参数是属性名
  9. {
  10. if($name='age'){
  11. return $this->age;
  12. }
  13. //echo '$name';
  14. }
  15. }
  16. $niu=new Person();
  17. //echo $niu->age;//在类的外部通过对象,你只能访问公共的属性,不能访问受保护和私有的

__set

触发时机: 对象在外部设置私有或者受保护成员属性值的时候调用(get是获取的时候调用,set是设置的时候调用)
该方法有两个参数:
参数1:成员属性名
参数2:要设置的值

  1. <?php
  2. class Person
  3. {
  4. public $name='小明';
  5. protected $age=18;
  6. private $height=187;
  7. //当你在外部试图通过对象来访问受保护的或者私有的成员属性时,就会自动触发__get()
  8. public function __get($name)//参数是属性名
  9. {
  10. if($name='age'){
  11. return $this->age;
  12. }
  13. //echo '$name';
  14. }
  15. public function __set($name,$value)
  16. {
  17. //var_dump($name,$age)
  18. if($name=='age'){
  19. $this->age=$value;
  20. }
  21. }
  22. }
  23. $niu=new Person();
  24. //echo $niu->age;//在类的外部通过对象,你只能访问公共的属性,不能访问受保护和私有的
  25. //在外面我们去设置它私有或者受保护的属性
  26. $niu->age=20;

外部可以通过unset销毁对象中的public属性(那么针对私有的或者受保护的你能不能销毁呢?)

__unset

unset可以销毁一个变量,isset可以判断这个变量有没有被设置过值。

触发时机:对象在外部销毁私有或者受保护成员属性的时候调用
该方法有一个参数:参数就是私有的成员属性名

  1. <?php
  2. class Person{
  3. public $name;
  4. protected $age;
  5. private $height;
  6. public function __unset($name) //有一个参数,就是你要销毁的属性名
  7. {
  8. if($name=='age'){
  9. unset($this->$name;)
  10. }
  11. }
  12. }
  13. $niu=new Person();
  14. //unset($niu->$name);//在类的外部我们可以通过unset来销毁类的公共属性
  15. unset($niu->$age);//会报错,自动触发__unset方法
  16. var_dump($niu);

__isset

触发时机:对象在外部判断私有或者受保护成员属性的时候调用
该方法有一个参数:参数就是私有的成员属性名

  1. <?php
  2. class Person{
  3. public $name;
  4. protected $age;
  5. private $height;
  6. public function __unset($name) //有一个参数,就是你要销毁的属性名
  7. {
  8. if($name=='age'){
  9. unset($this->$name);
  10. }
  11. }
  12. public function __set($name,$value)
  13. {
  14. if($name=='age')
  15. {
  16. $this->$name=$value;
  17. }
  18. }
  19. public function __get($name)
  20. {
  21. if($name=='age')
  22. {
  23. return $this->$name;
  24. }
  25. }
  26. public function __isset($name)
  27. {
  28. //在判断私有属性有没有被设置的时候就会自动的触发这个方法
  29. if($name=='age'){
  30. return isset($this->$name);
  31. }
  32. }
  33. $niu=new Person();
  34. //unset($niu->$name);//在类的外部我们可以通过unset来销毁类的公共属性
  35. //unset($niu->$age);//会报错,自动触发__unset方法
  36. //$niu->$age=100;
  37. // var_dump(isset($niu->age));

__construct:构造方法

触发时机:在创建对象的时候自动调用
这里我们经常做一些有关对象属性初始化的操作

__destruct: 析构方法

触发时机:在销毁对象的时候自动调用
脚本运行结束后$niu所占用的内存空间释放,释放的时候就是对象被销毁的时候,自动调用析构方法

代码总结:

  1. <?php
  2. //__get: 对象在外部访问私有成员属性或者保护属性的时候调用
  3. //__set:对象在外部设置私有属性或者保护成员属性值的时候调用
  4. //__unset:对象在外部销毁私有或者受把傲虎的成员属性的时候调用
  5. //__isset:对象在外部判断私有或者受保护成员属性的时候调用
  6. //__construct:在创建对象的时候自动调用
  7. //__destruct:在销毁对象的时候自动调用
  8. class Person{
  9. public $name='小明';
  10. protected $age=18;
  11. private $height=178;
  12. public function __get($name)
  13. {
  14. //echo '对象在外部访问私有成员属性或者保护属性的时候调用我';
  15. if($name=='age')
  16. {
  17. return $this->$name;
  18. }
  19. }
  20. public function __set($name,$value)
  21. {
  22. //echo '对象在外部设置私有属性或者保护成员属性值的时候调用';
  23. if($name=='age'){
  24. $this->$name=$value;
  25. }
  26. }
  27. public function __unset($name)
  28. {
  29. //echo '对象在外部销毁私有或者受把销毁的成员属性的时候调用';
  30. if($name='age')
  31. {
  32. unset($this->$name);
  33. }
  34. }
  35. public function __isset($name)
  36. {
  37. //echo '对象在外部判断私有或者受保护成员属性的时候调用';
  38. if($name='age')
  39. {
  40. return isset($this->$name);
  41. }
  42. }
  43. public function __construct()
  44. {
  45. echo '在创建对象的时候会自动调用我';
  46. }
  47. public function __destruct()
  48. {
  49. echo '在销毁对象的时候会自动调用我';
  50. }
  51. }
  52. //测试__get
  53. $xiaoming=new Person();
  54. var_dump($xiaoming->name);//string(6)"小明"
  55. echo '<br />';
  56. var_dump($xiaoming->age);//int(18)
  57. var_dump($xiaoming->height);//NULL
  58. //测试__set
  59. $niu=new Person();
  60. $niu->name='小牛';
  61. echo '<br />';
  62. echo $niu->name; //小牛
  63. $niu->age=20;//age是受保护的变量,不能直接设置,设置时会调用__set
  64. echo $niu->age;//20
  65. //测试__unset
  66. $ma=new Person();
  67. /*
  68. unset($ma->name);
  69. echo $ma->name;//unexpected '$ma'
  70. */
  71. //销毁私有或受保护的属性
  72. echo '<br />';
  73. /*
  74. unset($ma->age);
  75. echo $ma->age;//Undefined property: Person::$age这样就销毁成功了
  76. */
  77. //测试__isset
  78. $hong=new Person();
  79. var_dump(isset($niu->age));//bool(false)
  80. echo '<br />';
  81. $hong->age=25;
  82. var_dump(isset($niu->age));//还是false
  83. //所以不能轻易判断出私有属性和受保护的属性是否存在
  84. //设置完__isset之后就变成true了
  85. //测试__construct
  86. $jun=new Person(); //输出:在创建对象的时候会自动调用我
  87. //测试__destruct
  88. echo '<br />';
  89. unset($jun);

图片.png

__toString

触发时机: echo一个对象的时候触发 (把对象当成字符串使用的时候自动执行)
该函数需要return一个字符串

  1. <?php
  2. class Person{
  3. public $name;
  4. //要打印对象要写一个魔术方法
  5. public function __toString()//这个函数没有参数
  6. {
  7. return '我爱你中国';
  8. }
  9. }
  10. $niu = new Person();
  11. echo $niu;//不能通过echo来打印一个对象,要打印对象要写一个魔术方法
  12. //会打印出你return的字符串,这个字符串你可以打印这个对象自己的信息(拼接成一个字符串进行打印)

__invoke

触发时机:将对象当成函数的时候自动调用
图片.png

__debugInfo

触发时机: var_dump一个对象的时候触发
该函数需要return一个数组

  1. <?php
  2. class Person{
  3. public $name;
  4. public $age;
  5. public $height;
  6. //当通过var_dump打印对象的时候,我只想显示$age和$height
  7. public function __debugInfo()
  8. {
  9. return ['age'=>$this->age,'height'=>$this->height];
  10. }
  11. }
  12. $niu = new Person();
  13. var_dump($niu);

__call

触发时机:当调用一个不存在对象方法的时候触发
参数1:函数名
参数2:是一个数组,函数中的参数都被存放到这个数组中

  1. <?php
  2. class Person{
  3. public $name;
  4. public $age;
  5. public $height;
  6. //当你调用一个不存在的对象方法的时候就会自动调用__call
  7. public function test()
  8. {
  9. echo '这是test方法';
  10. }
  11. public function __call($name,$value)
  12. {
  13. var_dump($name,$value);
  14. }
  15. }
  16. $niu = new Person();
  17. var_dump($niu);
  18. $niu->demo(1,2,3);//调用一个不存在的对象

图片.png

__callStatic

触发时机:当调用一个不存在静态方法的时候触发
参数1:函数名
参数2:是一个数组,函数中的参数都被存放到这个数组中
[注]该方法也是static方法

call是调用对象方法
callStatic是调用静态方法


图片.png

序列化和反序列化

我们在学习sleep和wakeup之前我们要先了解序列化和反序列化
参考:简单了解反序列化 (好好好)
Y4师傅的反序列化文章(大大的好)
serialize:序列化
unserialize:反序列化

序列化后的内容只有成员变量,没有成员函数

  1. <?php
  2. class Person
  3. {
  4. public $name;
  5. public $age;
  6. public $height;
  7. public function __construct($name,$age,$height)
  8. {
  9. $this->name=$name;
  10. $this->age=$age;
  11. $this->height=$height;
  12. }
  13. }
  14. $niu=new Person('niu',19,180);
  15. //如果我想保存$niu这个对象怎么保存?我们知道程序运行结束之后$niu占用的内存空间已经被释放掉了,
  16. //$niu这个对象只有在程序运行的时候才存在,脚本一结束,这些信息就都没有了
  17. //我们可以通过写入文件的形式将它的名字、年龄、身高都写入到文件中,就保存到磁盘中了,永久存在
  18. //当你想要保存一个对象的时候,你就可以将它序列化
  19. $str=serialize($niu);//会返回一个字符串
  20. echo $str; //O:6:"Person":3:{s:4:"name";s:3:"niu";s:3:"age";i:19;s:6:"height";i:180;}
  21. //生成字符串之后就可以写入文件中了
  22. file_put_contents('niu.txt', $str);//这样就达到完美保存一个对象的目的,不管程序有没有运行结束,这个对象都已经保存在本地

__sleep

触发时机:在序列化一个对象的时候调用
返回值:必须是一个数组,数组中写你想要序列的成员属性名

  1. <?php
  2. class Person
  3. {
  4. public $name;
  5. public $age;
  6. public $height;
  7. public function __construct($name,$age,$height)
  8. {
  9. $this->name=$name;
  10. $this->age=$age;
  11. $this->height=$height;
  12. }
  13. public function __sleep()
  14. {
  15. //echo '我要睡觉了';
  16. //现在只想序列化年龄和身高,所以就只需要返回属性即可
  17. return ['age','height'];//age和height都是一个属性名字符串
  18. }
  19. }
  20. $niu=new Person('niu',19,180);
  21. //如果我想保存$niu这个对象怎么保存?我们知道程序运行结束之后$niu占用的内存空间已经被释放掉了,
  22. //$niu这个对象只有在程序运行的时候才存在,脚本一结束,这些信息就都没有了
  23. //我们可以通过写入文件的形式将它的名字、年龄、身高都写入到文件中,就保存到磁盘中了,永久存在
  24. //当你想要保存一个对象的时候,你就可以将它序列化
  25. $str=serialize($niu);//会返回一个字符串
  26. echo $str; //O:6:"Person":3:{s:4:"name";s:3:"niu";s:3:"age";i:19;s:6:"height";i:180;}
  27. //生成字符串之后就可以写入文件中了
  28. file_put_contents('niu.txt', $str);//这样就达到完美保存一个对象的目的,不管程序有没有运行结束,这个对象都已经保存在本地
  29. //现在通过序列化将我们对象的年龄、名字、身高都保存到文件中,现在又一个需求,我只想让你保存年龄和身高怎么办?要用__sleep
  30. //O:6:"Person":2:{s:3:"age";i:19;s:6:"height";i:180;}

__wakeup

触发时机:在反序列化一个对象的时候调用
反序列成功之后,想要让对象执行一些初始化方法,可以写到这个函数中

  1. <?php
  2. class Person
  3. {
  4. public $name;
  5. public $age;
  6. public $height;
  7. public function __construct($name,$age,$height)
  8. {
  9. $this->name=$name;
  10. $this->age=$age;
  11. $this->height=$height;
  12. }
  13. public function __sleep()
  14. {
  15. //echo '我要睡觉了';
  16. //现在只想序列化年龄和身高,所以就只需要返回属性即可
  17. return ['age','height'];//age和height都是一个属性名字符串
  18. }
  19. public function __wakeup()
  20. {
  21. echo '我睡醒了';
  22. }
  23. }
  24. $niu=new Person('niu',19,180);
  25. //你保存到本地一个对象字符串之后,现在我想让你把这个对象再恢复,怎么恢复?
  26. //首先将这个字符串先读进来
  27. $str=file_get_contents('niu.txt');
  28. //反序列化
  29. $obj=unserialize($str); //通过你序列化的一个字符串,我可以反序列化成一个对象,在你反序列化的时候他会先执行__wakeup,在这里面你可以将自己的一些属性再设置一下
  30. var_dump($obj);
  31. /*
  32. 输出:
  33. 我睡醒了object(Person)#2 (3) {
  34. ["name"]=>
  35. NULL
  36. ["age"]=>
  37. int(19)
  38. ["height"]=>
  39. int(180)
  40. }
  41. */

__clone

触发时机:在克隆一个对象的时候调用
在这里面可以对克隆出来的对象的属性做一些操作

  1. <?php
  2. class Person
  3. {
  4. public $name;
  5. public $age;
  6. public $height;
  7. public function __wakeup()
  8. {
  9. echo '我睡醒了';
  10. }
  11. public function __clone()
  12. {
  13. //这里面你可以对克隆出来的对象的属性做一些操作,比如我不想让他的年龄跟我一样
  14. $this->age=20;//可以对属性做一个简单的初始化
  15. }
  16. }
  17. $niu=new Person('niu',19,180);
  18. $obj=clone $niu;//将$niu这个对象克隆一份(就是制造一个一模一样的对象)
  19. var_dump($obj);
  20. //当你在克隆的时候会自动调用__clone

__autoload(这是唯一一个写在类外的魔术方法)

触发时机: new一个对象的时候,当前脚本没有这个类,那么会触发这个方法
参数: 就是该类的类名字符串

Dog.php

  1. <?php
  2. class Dog{
  3. function wang(){
  4. echo '汪汪';
  5. }
  6. }

moshu.php

  1. <?php
  2. class Person
  3. {
  4. public $name;
  5. public $age;
  6. public $height;
  7. public function __autoload($className)//自动加载
  8. {
  9. $file=$className.'php'; //通过类名找到文件名
  10. include $file;
  11. }
  12. }
  13. $dog=new Dog();//没有Dog这个类,当你去创建一个不存在的类的对象的时候,就会自动调用__autoload这个方法,这个方法是唯一写在类外的方法
  14. $dog->wang();//汪汪
  15. //工作中一个类就是一个完整的文件,文件名要和类名相同