对象序列化和反序列化
<?php
//对象序列化:serialize — 产生一个可存储的值的表示
echo serialize(123);//输出结果:i:123;i表示为整形int
echo serialize('PHP');//s:3:"PHP";string字符串型和3长度
echo '<hr>';
class Dad
{
public $name='小二';
protected $age=30;
private $sex='man';
}
class Son extends Dad
{
private $address='地球';
protected $deposit=50000;
public function __get($name)
{
return $this->name;
}
protected function sx()
{
return __METHOD__;
}
// serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。__sleep() 不能返回父类的私有成员的名字。
public function __sleep():array
{
//序列化需要返回的属性
return ['name','age'];
}
//__wakeup反序列化先修改值/字符串
public function __wakeup()
{
$this->name='二狗子';
}
}
$son = new Son();
//序列化对象
// echo serialize($son);
echo '<hr>';
//结果:
// O:3:"Son(被序列化的类名)":5:{s:12:"Sonaddress(类中私有属性)";s:6:"地球";s:10:"*deposit(*表示受保护属性)";i:50000;s:4:"name";s:6:"小二";s:6:"*age";i:30;s:8:"Dadsex(父类私有属性)";s:3:"man";}
// file_put_contents — 将一个字符串写入文件
file_put_contents('obj.txt',serialize($son));
// file_get_contents — 将整个文件读入一个字符串
$str=file_get_contents('obj.txt');
echo $str;
echo '<hr>';
//反序列化unserialize
$obj=unserialize($str);
var_dump($obj);
// object(Son)#2 (5) { ["address":"Son":private]=> string(6) "地球" ["deposit":protected]=> int(50000) ["name"]=> string(6) "小二" ["age":protected]=> int(30) ["sex":"Dad":private]=> string(3) "man" }
//Son这个类一定要有,没有则失败
反序列化重写连接数据库
<?php
// __sleep(), __wackup()
// 创建数据库连接类,
// 1. 实例化的时候, 自动连接,并创建连接对象
// 2. 外部对连接对象序列化时, 获取到连接参数
// 3. 反序列化的时候, 自动重新连接数据库
class connection
{
//当前连接对象
protected $link;
//当前连接参数
private $params=[];
//构造方法,完成数据库连接
public function __construct($dsn,$username,$password)
{
$this->params['dsn']=$dsn;
$this->params['username']=$username;
$this->params['password']=$password;
//连接过程写到connect方法里面去
$this->connect();
}
public function connect()
{
//转为索引数组拿值
try{
$this->link=new PDO(...array_values($this->params));
// $this->link = new PDO('mysql:host=127.0.0.1;dbname=Demo', 'root','123456');
}catch(Exception $e){
echo $e->getMessage();
}
}
//序列化返回连接参数
public function __sleep()
{
return['params'];
}
//反序列化自动连接
public function __wakeup()
{
$this->connect();
}
//测试
public function select($sql)
{
return $this->link->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
}
// 客户端
$db=new Connection('mysql:host=localhost;dbname=Demo','root','123456');
print_r($db->select('select * from user_list limit 3'));
echo '<hr>';
$str= serialize($db);
echo $str;
echo '<hr>';
//反序列化后会返回新对象,重写连接查询
$obj=unserialize($str);
print_r($obj->select("select * from user_list limit 3"));
__clone克隆新对象
<?php
//__clone克隆出全新的对象
class Demo
{
public $name='痞子';
public function __clone()
{
$this->name='茄子';
}
}
$demo=new Demo();
$demo2= clone $demo;
echo $demo2->name;
匿名类适合场景
<?php
// //匿名类
// class Demo
// {
// public function Test($name)
// {
// return $name;
// }
// }
// //进化论:原始
// // $demo=new Demo();
// // echo $demo->Test('张三');
// //进化1
// echo (new Demo())->Test('李四');
// //进化2-->成为匿名类
// echo (new class
// {
// public function Test1($age)
// {
// return $age;
// }
// }
// )->Test1('333');
//匿名类适用场景:部分接口,仅当前文件/项目使用
interface iDb
{
public function __construct(...$params);
}
$res = (new class('mysql:host=localhost;dbname=Demo','root','123456') implements iDb
{
private $db = null;
public function __construct(...$params)
{
$this->db = new PDO($params[0],$params[1],$params[2]);
}
/**
* @param string $where 条件查询 例如: id = 1
*/
public function select($where = "")
{
$where = empty($where) ? null : ' WHERE ' . $where;
try {
# 没有条件的情况下的SQL语句
# SELECT * FROM user_list 这里是空' ' LIMIT 1;
# 有WHERE的情况下的SQL语句 最终拼装出来的是: WHERE id=1
# SELECT * FROM user_list WHERE id=1 LIMIT 1;
return $this->db->query("select * from user_list {$where} limit 1")->fetchAll(PDO::FETCH_ASSOC);
}catch(PDOException $e){
// 输出异常信息
var_dump($e->getMessage());
}
}
}
)->select();
printf('<pre>%s</pre>', print_r($res,true));
//匿名类场景2:函数,参数中
// 正常写:
// function get(object $user , string $name)
// {
// return $user->Test($name);
// }
// class User
// {
// public function Test($name)
// {
// return "我的名字是:". $name;
// }
// }
// $user = new User;
// echo get($user,'王老五');
//简单写:
function get(object $A , string $B)
{
return $A->Demo($B);
}
echo get(
//创建匿名类
new class()
{
public function Demo($B)
{
return "我告诉你我是谁,".$B;
}
},'二逼'
);
总结:真是一个细腻的脑力活,连接数据库这里老是因为小问题都抄错,比如:需要一个空格,比如分号,逗号这里。