文章目录
一、基础概念
为什么要序列化 https://blog.csdn.net/xlgen157387/article/details/79840134
什么是序列化 https://blog.csdn.net/u011215133/article/details/51177843
序列化与反序列化是开发过程中不可或缺的一步,简单来说,序列化是将对象转换成字节流的过程,而反序列化的是将字节流恢复成对象的过程。序列化与序列化主要解决的是数据的一致性问题
序列化: 将数据结构或对象转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程
- 目的
①以某种存储形式使自定义对象持久化;
②将对象从一个地方传递到另一个地方。
③使程序更具维护性。
- 为什么要序列化
简单来说序列化就是一种用来处理对象流的机制。所谓对象流也就是将对象内容进行流化(I/O)。直接对对象流进行读写操作时会引发一些问题(例如对象引用时的一致性考虑),而序列化机制正是用来解决这些问题的!
反序列化:将序列化后的对象字节流,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。
二,php的序列化与反序列化
所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示(把复杂的数据类型压缩到一个字符串中)。unserialize()函数能够重新把字符串变回php原来的值。
serialize()
序列化
unserialize()
反序列化
【实列1】对字符串和数字序列化
<?php
//对int型序列化
$aa = 111;
var_dump($aa);
echo "<br>";
echo serialize($aa) . "<br>";
//对字符串序列化
$bb = "hello!";
var_dump($bb);
echo "<br>";
echo serialize($bb) ;
?>
int(111)
i:111;
string(6) “hello!”
s:6:“hello!”;
【实列2】对数组序列化
<?php
$name = array('a' => 'tom' ,'b' => 'jack' , 'c' => 'rose');
var_dump($name);
echo "<br>";
$s = serialize($name); //返回一个包含字节流的字符串
echo $s . "<br>";
var_dump($s); //查看s的变量类型
//string(62) "a:3:{s:1:"a";s:3:"tom";s:1:"b";s:4:"jack";s:1:"c";s:4:"rose";}"
?>
【序列化前】 array(3) { [“a”]=> string(3) “tom” [“b”]=> string(4) “jack” [“c”]=> string(4) “rose” }
【序列化后】 a:3:{s:1:“a”;s:3:“tom”;s:1:“b”;s:4:“jack”;s:1:“c”;s:4:“rose”;}
☞对返回的字符串的说明
“ 结构类型a为数组:属性(成员)个数 :{ 属性名类型:长度:名称;值类型:长度:值 } ”
👍👍👍【实列3】对对象序列化
注意 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。
.
为什么要序列化
- 对象无对应的实体,程序结束后自动消失,想要保存则需序列化。
.
怎么就序列化了?
- 将对象转换为二进制的字符串进行描述
.
序列化函数
serialize(对象)
将一个对象转换成一个字符串
unserialize(序列化后的字符串)
将字符串还原为一个对象
eg:一个序列化的实列
<?php
class fruit
{
//定义属性
public $name;
public $price;
public $change;
//定义方法
public function __construct($name_value,$price_value,$change_value)
{
$this->name = $name_value;
$this->price = $price_value;
$this->change = $change_value;
}
}
$obj = new fruit("banana",3.7,"+0.3");
echo $obj->name . "<br>";
echo $obj->change . "<br>";
var_dump($obj);
echo "<br>------序列化后-----<br>";
$s = serialize($obj);
echo $s . "<br>";
echo "<br>------反序列化后-----<br>";
$obj2 = unserialize($s);
var_dump($obj2);
echo "<br>" . $obj2->name;
?>
运行结果
banana
+0.3
object(fruit)#1 (3) { [“name”]=> string(6) “banana” [“price”]=> float(3.7) [“change”]=> string(4) “+0.3” }
------序列化后-----
O:5:“fruit”:3:{s:4:“name”;s:6:“banana”;s:5:“price”;d:3.7000000000000002;s:6:“change”;s:4:"+0.3";}
.
------反序列化后-----
object(fruit)#2 (3) { [“name”]=> string(6) “banana” [“price”]=> float(3.7) [“change”]=> string(4) “+0.3” }
banana
O代表结构类型为类:5表示类名长度:类名:属性个数 { 属性名类型:长度:名称 ;值类型:长度:值;}
2.1 php中的部分魔法函数
PHP类中有一种特殊函数体的存在叫魔法函数,magic函数命名是以符号__开头的,比如 __construct, __destruct, __toString, __sleep, __wakeup等等。这些函数在某些情况下会自动调用
①构造函数☞ __construct()
作用: 通常用于初始化对象的属性
自动调用与: 对象创建时自动调用
...........
...........
public function __construct($name_value,$price_value,$change_value)
{
$this->name = $name_value;
$this->price = $price_value;
$this->change = $change_value;
}
}
$obj = new fruit("banana",3.7,"+0.3"); //创建对象时自动调用构造函数
②析构函数☞ __destruct()
自动调用与: 当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。
析构函数无参数
eg:一个实列
<?php
class A
{
public $name = "is A";
public function __destruct()
{
echo "当前对象已被销毁";
}
}
//定义一个对象
$obj = new A();
echo "当前对象的name属性为:" . $obj->name . "<br>";
//销毁对象
echo "<br>----销毁对象后----<br>";
unset($obj);
?>
当前对象的name属性为:is A
.
----销毁对象后----
当前对象已被销毁
③对对象的封装时的魔法函数
__get()
外部访问不存在或者=私有属性时调用
__set()
外部访问不存在或者=私有属性时调用
__isset()
在外部检测是否存在某个属性时调用
__unset()
外部销毁某个私有属性时调用时调用
④序列化和反序列化的魔法函数
__sleep()
自动调用时机:序列化时
作用:将允许序列化的对象放在一组数组中返回,序列化时只序列化指定的属性。
<?php
class fruit
{
//定义属性
public $name;
public $price;
public $change;
//定义方法
public function __construct($name_value,$price_value,$change_value)
{
$this->name = $name_value;
$this->price = $price_value;
$this->change = $change_value;
}
//定义sleep魔术方法
public function __sleep()
{
return ["name"];
}
}
$obj = new fruit("apple",10,"-0.2");
var_dump($obj);
echo "<br>对象obj的price属性为:" . $obj->price . "<br>";
echo "<br>------序列化后-----<br>";
$s = serialize($obj);
echo $s . "<br>";
echo "<br>------反序列化后-----<br>";
$obj2 = unserialize($s);
var_dump($obj2);
?>
__wakeup()
自动调用时机:反序列化时
作用:反序列化时修改属性(对重新生成的对象的属性进行修改),或重新建立数据库连接,或执行其它初始化操作。
eg 1 :
<?php
class fruit
{
//定义属性
public $name;
public $price;
public $change;
//定义方法
public function __construct($name_value,$price_value,$change_value)
{
$this->name = $name_value;
$this->price = $price_value;
$this->change = $change_value;
}
//定义sleep魔术方法
public function __sleep()
{
return ["name"];
}
//定义wakeup魔术方法
public function __wakeup()
{
$this ->price=20;
}
}
$obj = new fruit("apple",10,"-0.2");
var_dump($obj);
echo "<br>对象obj的price属性为:" . $obj->price . "<br>";
echo "<br>------序列化后-----<br>";
$s = serialize($obj);
echo $s . "<br>";
echo "<br>------反序列化后-----<br>";
$obj2 = unserialize($s);
var_dump($obj2);
?>
eg 2 : 重新建立数据库连接
<?php
class Connection
{
protected $link;
private $server, $username, $password, $db;
public function __construct($server, $username, $password, $db)
{
$this->server = $server;
$this->username = $username;
$this->password = $password;
$this->db = $db;
$this->connect();
}
private function connect()
{
$this->link = mysql_connect($this->server, $this->username, $this->password);
mysql_select_db($this->db, $this->link);
}
public function __sleep()
{
return array('server', 'username', 'password', 'db');
}
public function __wakeup()
{
$this->connect();
}
}
?>