php序列化和反序列化

一,什么是序列化和反序列化

序列化

序列化是将对象转化为可存储或传输的字符串格式的过程。在php中,可以使用serialize()函数将对象,数组或其它数据类型序列化称为一个字符串,以便将其保存到文件或者进行网络传输。

反序列化

反序列化是将之前序列化得到的字符串重新转换为原始的php数据结构或对象的过程。在php中,可以使用unserialize()函数对序列化后的字符串进行反序列化操作。

二,为什么要序列化和反序列化

在php中,序列化和反序列化是用来实现数据持久化,数据传输和数据存储的重要概念。

既然是面向对象的操作,那我们先了解什么是面向对象和面向过程。

举个例子

过年了,家里要打扫卫生。

你先扫地,再擦桌子,再拖地。一件一件的完成。这就是面向过程。

你扫地,爸爸擦桌子,妈妈拖地。一起完成,各干各的。这就是面向对象。

关键区别在于,面向过程的实现方式更加关注解决问题的步骤和过程。

而面向对象的实现更加关注对象的行为和状态。

三,什么是类和对象

什么是类?

类是面向对象编程中的一个关键概念,它是对具有相似特征和行为的对象的抽象描述,类定义了对象可以拥有的属性(成员变量)和行为(方法)。

什么是对象?

对象是类的实例化产物,是类的具体实体。

直接看代码

brand="奥迪";
$a->type="rs7";
$a->color="black";
//调用方法
$a->move();
$a->speed_up();
$a->stop();
echo $a->brand;
?>

运行结果

php序列化和反序列化_第1张图片

这里的类就是car,对象就是$a。

类的继承

子类和父类,说白了就是爸爸和儿子的关系,子类可以继承父类的属性和方法。

代码展示

电池容量='120kmh';
$b->brand='雅迪';
echo "
"; $b->speed_up(); $b->充电(); echo $b->brand; ?>

从上图可以看出,我定义了一个名为ect的子类,而定义子类需要extends关键字。

在子类中,我只定义了一个属性和一个方法,但是我在调用时,却可以直接调用父类的属性和方法。这儿就是类的继承。

运行结果

php序列化和反序列化_第2张图片

除了类的继承,访问修饰符也同样重要。

四,访问修饰符

一共有三个访问修饰符,public,protected,private

在php类中不写访问修饰符默认的访问权限为public

调用属性和方法也有三种情况,分别是类中,类外,子类。

php序列化和反序列化_第3张图片

由图可以看到,public无论在哪里都可以访问,protected只有在类中和子类中可以访问,private只可以在类中调用。

name;
		echo '在类自身调用:'.$this->sex;
		echo '在类自身调用'.$this->age;
		//在方法指定属性需要$this
	}
}


$a=new people();
echo '在类外调用'.$a->name;
echo '在类外调用'.$a->sex;
echo '在类外调用'.$a->age;
$a->speak();
?>

运行结果

php序列化和反序列化_第4张图片

可以看到只输出了学生,因为学生的属性名name的修饰符为public,在哪里都可以访问,而sex和age就不行了,都不能在类外调用。

name;
		echo "
"; echo '在类自身调用:'.$this->sex; echo "
"; echo '在类自身调用'.$this->age; echo "
"; //在方法指定属性需要$this } } $a=new people(); //echo '在类外调用'.$a->name; //echo "
"; // echo '在类外调用'.$a->sex; // echo '在类外调用'.$a->age; //虽然不能直接调用属性,但是可以调用方法,方法中的属性也属于类中调用 $a->speak(); ?>

当我不在类外调用类的属性时,直接在类外调用方法。

php序列化和反序列化_第5张图片

发现成功输出,虽然sex和age不能再类外调用,但是我直接在类外调用方法,方法调用了三个属性,相当于还是在类中,因为方法在类中。

name;
		echo "
"; echo '在类自身调用:'.$this->sex; echo "
"; echo '在类自身调用'.$this->age; echo "
"; //在方法指定属性需要$this } } class student extends people{ function speak1() { echo '在子类调用:'.$this->name; echo "
"; echo '在子类调用:'.$this->sex; echo "
"; echo '在子类调用:'.$this->age; } } //public,protected修饰符在子类中都能调用 $c=new student(); $c->speak1(); ?>

运行结果

php序列化和反序列化_第6张图片

创建一个子类student,输出结果发现 age属性没有被调用,以为它的修饰符时private,只能在类中被调用,不能再子类和类外调用。

说完修饰符,我们就就该正式进入序列化和反序列化的篇章了。

五,演示

序列化

用serialize()函数将对象序列化成字符串。

php序列化和反序列化_第7张图片

// O表示对象类型
// 6表示类名的长度
// "people"表示类名
// 3表示类中有三个属性
// s表示字符型
// 11表示属性名的长度,因为age是私有属性,所以它的属性名的长度组成是一个空格+类名+一个空格+属性名
// peopleage这里表示私有属性的属性名,在people前后有两个空格
// i表示数字型
// 18表示私有属性age的值
// name是public修饰符,看到什么就是什么
// 9表示protected修饰符的长度,长度组成一个空格+*+一个空格+属性名
//对象的方法不会在序列化显示,但是它是有的

总结,不同修饰符,序列化后的属性名长度不同。

public 不变

protected 一个空格+*+一个空格+属性名

private 一个空格+类名+一个空格+属性名 

反序列化

";
var_dump(unserialize($b));
?>

 反序列化的结果不能用echo函数,只能用print_r(),var_dump()。

php序列化和反序列化_第8张图片

第一行时print_r()打印的结果,第二行是var_dump()打印的结果,这里的#2没有实际意义,只是php里面的标识符。不管是print_r(),还是var_dump()都可以准确的打印出属性的访问修饰符。 

 

你可能感兴趣的:(php,开发语言)