博客列表 >其它常用魔术方法与实战

其它常用魔术方法与实战

王佳祥
王佳祥原创
2020年07月30日 08:50:47577浏览

其它常用魔术方法与实战

一、sleep()与weakup()

  • __sleep()用serialize关键字序列化时被自动调用的魔术方法

  • __wakeup()用unserialize关键字反序列化时被自动调用的魔术方法

案例1:

  1. <?php
  2. //序列化
  3. //echo serialize('孙悟空');
  4. //echo serialize([1,2,3,true,null]);
  5. class User
  6. {
  7. public $name = '遥控飞机';
  8. public $price = 4000;
  9. public $num = 3;
  10. //序列化时自动调用__sleep()魔术方法
  11. public function __sleep():array
  12. {
  13. return ['name','price','num'];
  14. }
  15. //反序列化时自动调用
  16. public function __wakeup()
  17. {
  18. $this->price = 1000;
  19. }
  20. }
  21. $user = new User();
  22. echo serialize($user),'<br>';
  23. //序列化数据的目的是将数据进行传输保存
  24. file_put_contents('obj.txt',serialize($user));
  25. $str = file_get_contents('obj.txt');
  26. echo gettype($str).'<br>';
  27. //反序列化
  28. $obj = unserialize($str);
  29. echo gettype($obj).'<br>';
  30. echo $obj->name . ':价格:' . $obj->price . ',数量:' , $obj->num;


案例2:

  1. <?php
  2. //__sleep()和__wakeup()实战
  3. //自定义数据库连接类
  4. //功能
  5. //1.类实例化,自动连接数据库,一定会生成一个:连接对象
  6. //2.将这个连接对象序列化,获取到连接参数
  7. //3.反序列化,自动重新连接数据库
  8. //连接类
  9. class Connection
  10. {
  11. //数据库连接参数
  12. private $params = [];
  13. //连接对象
  14. private $link;
  15. //构造方法
  16. public function __construct($dsn,$username,$password)
  17. {
  18. //1.连接参数的初始化
  19. $this->params['dsn'] = $dsn;
  20. $this->params['username'] = $username;
  21. $this->params['password'] = $password;
  22. $this->connect();
  23. //2.连接数据库
  24. //$this->link = new PDO(...$this->params);
  25. }
  26. //连接数据库
  27. public function connect()
  28. {
  29. //array_values()把关联数组转换为索引数组
  30. $this->link = new PDO(...array_values($this->params));
  31. }
  32. //将这个连接对象序列化,获取到连接参数
  33. public function __sleep():array
  34. {
  35. return ['params'];
  36. }
  37. //反序列化,自动重新连接数据库
  38. public function __wakeup()
  39. {
  40. $this->connect();
  41. }
  42. public function select($sql)
  43. {
  44. return $this->link->query($sql)->fetchAll(PDO::FETCH_ASSOC);
  45. }
  46. }
  47. $dsn = 'mysql:host=localhost;dbname=tp5';
  48. $username = 'root';
  49. $password = 'wang1111';
  50. $db = new Connection($dsn,$username,$password);
  51. //var_dump($db);
  52. $str = serialize($db);
  53. echo $str.'<hr>';
  54. //print_r(unserialize($str));
  55. print_r($db->select('SELECT * FROM user LIMIT 3'));
  56. echo '<hr>';
  57. //3.反序列化,自动重新连接数据库
  58. $link = unserialize($str);
  59. print_r($link);


二、__toString()

  • __toString() 方法用于一个类被当成字符串输出时自动调用该魔术方法
  1. <?php
  2. //tostring()
  3. class User
  4. {
  5. public function __toString()
  6. {
  7. return 'Hello';
  8. }
  9. }
  10. //将这个类的实例,当成字符串打印
  11. $user = new User();
  12. echo $user;
  13. class DbException extends PDOException
  14. {
  15. public function __toString()
  16. {
  17. return <<< DBE
  18. <table border="1px">
  19. <tr>
  20. <td>编号</td>
  21. <td>信息</td>
  22. <td>文件</td>
  23. <td>行号</td>
  24. </tr>
  25. <tr>
  26. <td>$this->code</td>
  27. <td>$this->message</td>
  28. <td>$this->file</td>
  29. <td>$this->line</td>
  30. </tr>
  31. </table>
  32. DBE;
  33. }
  34. }
  35. try{
  36. $db = new PDO('mysql:host=localhost;dbname=tp5','root','wang11112');
  37. }catch(PDOException $e){
  38. $error = new DbException('连接错误',1001);
  39. echo $error;
  40. }


三、匿名类

  • 匿名类可以创建一次性的简单对象

  • 可以传递参数到匿名类的构造器,也可以扩展(extend)其他类、实现接口(implement interface),以及像其他普通的类一样使用

  1. <?php
  2. //匿名类的应用场景
  3. //1.实现接口的部分功能
  4. interface iDb
  5. {
  6. public function __construct(...$params);
  7. }
  8. //当前这个接口中的数据连接操作应该支持PDO,mysqli
  9. //mysqlu实现
  10. class My_mysqli implements iDb
  11. {
  12. private $db = null;
  13. public function __construct(...$params)
  14. {
  15. $this->db = new mysqli($params[0],$params[1],$params[2],$params[3]);
  16. echo '数据库连接成功';
  17. }
  18. public function select()
  19. {
  20. return $this->db->query('SELECT * FROM user LIMIT 2')->fetch_all(MYSQLI_ASSOC);
  21. }
  22. }
  23. $mysqli = new My_mysqli('localhost','root','wang1111','tp5');
  24. print_r($mysqli->select());
  25. echo '<hr>';
  26. //匿名类实现
  27. $users = ( new class ('localhost','root','wang1111','tp5') implements iDb{
  28. private $db = null;
  29. public function __construct(...$params)
  30. {
  31. $this->db = new mysqli($params[0],$params[1],$params[2],$params[3]);
  32. echo '数据库连接成功';
  33. }
  34. public function select()
  35. {
  36. return $this->db->query('SELECT * FROM user LIMIT 2')->fetch_all(MYSQLI_ASSOC);
  37. }
  38. })->select();
  39. print_r($users);
  40. echo '<hr>';
  41. //用pdo来实现
  42. class My_pdo implements iDb
  43. {
  44. private $db = null;
  45. public function __construct(...$params)
  46. {
  47. $this->db = new PDO($params[0],$params[1],$params[2]);
  48. echo '数据库连接成功';
  49. }
  50. public function select()
  51. {
  52. return $this->db->query('SELECT * FROM user LIMIT 1')->fetchAll(PDO::FETCH_ASSOC);
  53. }
  54. }
  55. $mypdo = new My_pdo('mysql:host=localhost;dbname=tp5','root','wang1111');
  56. print_r($mypdo->select());
  57. echo '<hr>';
  58. //用匿名类来实现
  59. $users2 = ( new class ('mysql:host=localhost;dbname=tp5','root','wang1111') implements iDb{
  60. private $db = null;
  61. public function __construct(...$params)
  62. {
  63. $this->db = new PDO($params[0],$params[1],$params[2]);
  64. echo '数据库连接成功';
  65. }
  66. public function select()
  67. {
  68. return $this->db->query('SELECT * FROM user LIMIT 2')->fetchAll(PDO::FETCH_ASSOC);
  69. }
  70. })->select();
  71. print_r($users2);
  72. echo '<hr>';


四、学习总结

  • 序列化时自动调用__sleep()魔术方法

  • 反序列化时自动调用__wakeup()魔术方法

  • 当echo一个实例化的类时,自动调用__toString()魔术方法

  • 匿名类,没有名称的类,通常赋值给一个变量

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议