Blogger Information
Blog 47
fans 1
comment 0
visits 53046
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP - 对象的序列化,克隆与异常类,匿名类
晴天
Original
723 people have browsed it

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,加入这个类真的只用一次 不如直接用匿名函数解决

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:匿名类用处非常大, 只是你还没接触到项目测试工作
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post