博客列表 >PHP - 对象的序列化,克隆与异常类,匿名类

PHP - 对象的序列化,克隆与异常类,匿名类

晴天
晴天原创
2020年05月10日 22:08:29722浏览

1.序列化

名称 描述
serialize() 将一个值或一个数组进行序列化
unserialize() 将一个序列化的值进行反序列化
__sleep() 魔术方法,当序列化一个对象的时候自动调用
__wakeup 魔术方法,当反序列化一个对象的时候自动调用

演示代码:

  1. <?php
  2. //序列化 可以是整数 字符串 数组
  3. //整数
  4. $mub = 10;
  5. //进行序列化
  6. $smub = serialize($mub);
  7. echo $smub; //输出 i:10;
  8. //进行反序列化
  9. $umub = unserialize($smub);
  10. echo $umub; //输出 10
  11. echo '<hr>';
  12. //字符串
  13. $str = '中国万岁';
  14. //序列化
  15. $s_str = serialize($str);
  16. echo $s_str; //输出 s:12:"中国万岁"; s表示string字符串 12表示长度 四个字符表示一个中文
  17. //反序列化
  18. $u_str = unserialize($s_str);
  19. echo $u_str; //输出 中国万岁
  20. echo '<hr>';
  21. //数组
  22. $arr = [80, 'hello', true, null, [12,34]];
  23. //序列化
  24. $s_arr = serialize($arr);
  25. echo $s_arr;
  26. //输出 a:5:{i:0;i:80;i:1;s:5:"hello";i:2;b:1;i:3;N;i:4;a:2:{i:0;i:12;i:1;i:34;}}
  27. //反序列化
  28. $u_arr = unserialize($s_arr);
  29. print_r($u_arr);
  30. //输出 Array
  31. //(
  32. // [0] => 80
  33. // [1] => hello
  34. // [2] => 1
  35. // [3] =>
  36. // [4] => Array
  37. // (
  38. // [0] => 12
  39. // [1] => 34
  40. // )
  41. //
  42. //)

序列化一个对象
```php
<?php

//创建对象
//抽象类
//abstract class Dad
//{
// protected $name = ‘michael’;
// private $salary = 8000;
//}
//
////工作类
//class Son extends Dad
//{
// public $sex = ‘男’;
// protected $age = 40;
// private $isMarried = false;
//// 静态属性
//protected static $nationality = ‘美国/USA’;
////创建一个方法
//public function __get($name)
//{
// return $this->$name;
//}
//}
//
//$son = new Son();
////将序列化后的值保存到文件中
//file_put_contents(‘obj_index.txt’,serialize($son));

注意:序列化后的对象是不带有方法的,只序列化值 所以在反序列化时要引入这个类

//将输出的值保存到文件中 值: O:3:”Son”:5:{s:3:”sex”;s:3:”男”;s:6:”age”;i:40;s:14:”SonisMarried”;b:0;s:7:”name”;s:7:”michael”;s:11:”Dadsalary”;i:8000;}
// 带*表示私有属性private 带类名 Son。/Dad 表示protected属性

将类保存到另一个文件中 引入进来

//强制引入
require ‘for_index.php’;
//然后引入序列化文件并反序列化
$obj = unserialize(file_get_contents(‘obj_index.txt’));
//var_dump($obj);

//输出 object(Son)#1 (5) { [“sex”]=> string(3) “男” [“age”:protected]=> int(40) [“isMarried”:”Son”:private]=> bool(false) [“name”:protected]=> string(7) “michael” [“salary”:”Dad”:private]=> int(8000) }
//访问一下
$son = new Son();
echo $son->sex; //输出 男

  1. 关于序列化后的值 解读
  2. ![QQ截图20200510165422.png](https://i.loli.net/2020/05/10/B4tSikgDnAVseOv.png)
  3. ## 1.2 魔术方法 序列化
  4. ```php
  5. <?php
  6. // __sleep() __wakeup()
  7. //创建对象
  8. //抽象类
  9. abstract class Dad
  10. {
  11. protected $name = 'michael';
  12. private $salary = 8000;
  13. }
  14. //工作类
  15. class Son extends Dad
  16. {
  17. public $sex = '男';
  18. protected $age = 40;
  19. private $isMarried = false;
  20. // 静态属性
  21. protected static $nationality = '美国/USA';
  22. //创建一个方法
  23. public function __get($name)
  24. {
  25. return $this->$name;
  26. }
  27. //魔术方法 将在序列化所属类时 自动调用
  28. public function __sleep()
  29. {
  30. // 只允许将以下值进行序列化
  31. return['name','sex','isMarried'];
  32. }
  33. //魔术方法 将在反序列化所属类时自动调用
  34. public function __wakeup()
  35. {
  36. // 改变原序列化的值
  37. $this->name = 'kaiwen';
  38. $this->sex = '女';
  39. $this->isMarried = true;
  40. }
  41. }
  42. $son = new Son();
  43. //进行序列化
  44. $s_son = serialize($son);
  45. echo $s_son;
  46. //输出 O:3:"Son":3:{s:7:"*name";s:7:"michael";s:3:"sex";s:3:"男";s:14:"SonisMarried";b:0
  47. echo '<hr>';
  48. //进行反序列化
  49. var_dump(unserialize($s_son));
  50. //输出 object(Son)#2 (5) { ["sex"]=> string(3) "女" ["age":protected]=> int(40) ["isMarried":"Son":private]=> bool(true) ["name":protected]=> string(6) "kaiwen" ["salary":"Dad":private]=> int(8000) }

1.3 利用序列化连接数据库

  1. <?php
  2. //创建 链接类
  3. class Connection
  4. {
  5. protected $link;
  6. private $params = [];
  7. // 构造方法传参
  8. public function __construct($dsn, $username, $password)
  9. {
  10. $this->params['dsn'] = $dsn;
  11. $this->params['username'] = $username;
  12. $this->params['password'] = $password;
  13. // 转发
  14. $this->connect();
  15. }
  16. // 创建链接
  17. public function connect()
  18. {
  19. // 展开 返回数组中所有的值 不保留键名 array_values
  20. $this->link = new PDO(...array_values($this->params));
  21. }
  22. // 序列化的时候返回连接参数
  23. public function __sleep()
  24. {
  25. return ['params'];
  26. }
  27. // 反序列化时自动重新连接
  28. public function __wakeup()
  29. {
  30. $this->connect();
  31. }
  32. // 创建 查询方法
  33. public function select($sql)
  34. {
  35. return $this->link->query($sql)->fetchAll(PDO::FETCH_ASSOC);
  36. }
  37. }
  38. //传参
  39. $db = new Connection('mysql:host=localhost;dbname=php11.edu','php11.edu','php11.edu');
  40. //查询并打印
  41. print_r($db->select('SELECT * FROM `staffs` LIMIT 5'));
  42. //输出Array ( [0] => Array ( [id] => 1 [name] => 侯亮平 [age] => 40 [sex] => 1 [position] => 反贪局长 [mobile] => 13576543210 [hiredate] => 851356800 ) [1] => Array ( [id] => 2 [name] => 祁同伟 [age] => 46 [sex] => 1 [position] => 公安厅长 [mobile] => 13023456110 [hiredate] => 1420041600 ) [2] => Array ( [id] => 3 [name] => 高育良 [age] => 57 [sex] => 1 [position] => 政法书记 [mobile] => 15678789933 [hiredate] => 981734400 ) [3] => Array ( [id] => 4 [name] => 李达康 [age] => 51 [sex] => 1 [position] => 市委书记 [mobile] => 13088856110 [hiredate] => 1336838400 ) [4] => Array ( [id] => 5 [name] => 沙瑞金 [age] => 56 [sex] => 1 [position] => 省委书记 [mobile] => 18956490987 [hiredate] => 1179158400 ) )
  43. echo '<hr>';
  44. //序列化一下
  45. $str = serialize($db);
  46. echo $str;
  47. //输出 {s:18:"Connectionparams";a:3:{s:3:"dsn";s:37:"mysql:host=localhost;dbname=php11.edu";s:8:"username";s:9:"php11.edu";s:8:"password";s:9:"php11.edu";}}
  48. echo '<hr>';
  49. //反序列化
  50. $obj = unserialize($str);
  51. //会重新返回一个对象,所以要重新链接才能查询 使用__wakeup
  52. //查询
  53. print_r($db->select('SELECT * FROM `staffs` LIMIT 2'));
  54. //输出 Array ( [0] => Array ( [id] => 1 [name] => 侯亮平 [age] => 40 [sex] => 1 [position] => 反贪局长 [mobile] => 13576543210 [hiredate] => 851356800 ) [1] => Array ( [id] => 2 [name] => 祁同伟 [age] => 46 [sex] => 1 [position] => 公安厅长 [mobile] => 13023456110 [hiredate] => 1420041600 ) )

2. 对象的复制与__clone 克隆

对象是引用类型,将对象作为值,复制给其他变量时,遵循’引用传递’的规则

  1. <?php
  2. //创建一个类
  3. class User
  4. {
  5. public $name = 'michael';
  6. public $age = 40 ;
  7. // 创建魔术方法 该类被克隆是时调用
  8. public function __clone()
  9. {
  10. // 改一下age值 当被克隆时 返回这个值
  11. $this->age = 80;
  12. }
  13. }
  14. //先看一下引用
  15. $user1 = new User();
  16. //引用 等于起别名
  17. $user2 = $user1 ;
  18. //改一下值
  19. $user2->name = 'kaiwen';
  20. echo $user1->name; //输出 kaiwen
  21. //克隆 等于克隆一个新对象
  22. $user3 = clone $user1;
  23. echo $user3->name,'---',$user3->age;
  24. // 输出 kaiwen---80

3. __tostring()把对象当成字符串打印时自动调用

  1. <?php
  2. // __tostring() 当所在类被打印时自动调用
  3. //创建 类
  4. class User
  5. {
  6. public function __toString()
  7. {
  8. // 返回方法名
  9. return __METHOD__;
  10. }
  11. }
  12. $user = new User();
  13. //直接打印类会报错,使用魔术方法后可以正常打印
  14. echo $user;
  15. //使用魔术方法后 正常输出 User::__toString
  16. echo '<hr>';

4. 异常类

Exception : 三个属性 十个方法
属性 异常类外部不可访问 内部子类可以访问
|属性名|描述|
|-|-|
|protected string $message ;|异常消息内容|
|protected int $code ;|异常代码|
|protected string $file ;|抛出异常的文件名|
|protected int $line ;|抛出异常在该文件中的行号|

方法 final 最终方法 不允许被重写 不允许用户自定义
|方法名|描述|
|-|-|
|public __construct ([ string $message = "" [, int $code = 0 [, Throwable $previous = NULL ]]] )| — 异常构造函数|
|final public getMessage ( void ) : string| — 获取异常消息内容|
|final public getPrevious ( void ) : Throwable| — 返回异常链中的前一个异常|
|final public getCode ( void ) : int| — 获取异常代码|
|final public getFile ( void ) : string| — 创建异常时的程序文件名称|
|final public getLine ( void ) : int| — 获取创建的异常所在文件中的行号|
|final public getTrace ( void ) : array| — 获取异常追踪信息|
|final public getTraceAsString ( void ) : string| — 获取字符串类型的异常追踪信息|
|public __toString ( void ) : string| — 将异常对象转换为字符串|
|final private __clone ( void ) : void| — 异常克隆|

public __toString可以在子类中对这个方法进行自定义 这样就可以自定义出错的提示信息返回格式 美化
private __clone ( void ) : void 私有方法 禁止在外部克隆

演示代码

  1. <?php
  2. //异常类的典型应用
  3. //自定义异常语句
  4. class ErrException extends Exception
  5. {
  6. public function __toString()
  7. {
  8. return '邮箱格式错误';
  9. }
  10. }
  11. //检测一个值是否正确
  12. $email = '123qq.com';
  13. try {
  14. if (filter_var($email,FILTER_VALIDATE_EMAIL) === false){
  15. throw new ErrException($email);
  16. }
  17. } catch (ErrException $e){
  18. echo $e;
  19. }

5. 匿名类

  1. <?php
  2. //匿名类
  3. //创建一个类
  4. class User
  5. {
  6. public function name($name)
  7. {
  8. return 'hello' . $name;
  9. }
  10. }
  11. //常规访问
  12. $user = new User();
  13. echo $user->name('中国');
  14. //如果这个对象只调用一次
  15. echo (new User())->name('中国');
  16. //如果这个类只用一次
  17. echo(new class {
  18. public function Demo($name){
  19. return 'ddd'.$name;
  20. }
  21. })->Demo('撒旦');

6. 总结

个人感觉匿名类用处不大,简单了解一下ok,加入这个类真的只用一次 不如直接用匿名函数解决

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