一文带你吃透什么是PHP中的序列化

作者:金刀大菜牙 时间:2023-06-12 19:44:20 

1. php 中的序列化

在 PHP 中,序列化是将数据结构或对象转换为可以存储或传输的字符串表示的过程,经过序列化之后的对象或者数据结构,就可以保存到数据库、缓存或通过网络连接发送它,然后后面从序列化字符串重新创建对象或数据结构。

以下是如何在 PHP 中序列化对象的例子:

class User
{
   public $name;
   public $email;

   public function __construct($name, $email)
   {
       $this->name = $name;
       $this->email = $email;
   }
}

$user = new User('John', 'john@example.com');

$serializedUser = serialize($user);

echo $serializedUser;

此代码的输出将是$user对象的字符串表示形式,类似于:

O:4:"User":2:{s:4:"name";s:4:"John";s:5:"email";s:17:"john@example.com";}

PHP 中的序列化格式相当简单。序列化字符串由一系列数据类型和值组成,每个数据类型和值由冒号分隔。例如,整数的序列化字符串为i:123,而字符串的序列化字符串为s:5:"Hello"

要将此字符串反序列化回其原始形式,可以使用以下unserialize()函数:

$unserializedUser = unserialize($serializedUser);

echo $unserializedUser->name; // John
echo $unserializedUser->email; // john@example.com

2. 序列化和反序列化过程中的钩子

PHP 中有两个钩子可用于与此过程进行交互。你可以在一个类中定义这些钩子函数,它会在你序列化或者反序列化对象的时候自动调用。这对于在序列化或取反列化对象时执行自定义操作很有用,例如记录或验证。

__sleep() 钩子:这个钩子在序列化时被调用。在对象的属性被序列化之前,它允许开发人员指定哪些属性应该被序列化,哪些属性不被序列化。

class MyClass
{
   private $data;
   private $secret;

   public function __sleep() {
       return ['data'];
   }
}

__wakeup() 钩子:这个钩子在反序列化时被调用。在对象的属性被反序列化之后,它允许开发人员在对象被反序列化后对其执行任何必要的初始化或设置。

class MyClass
{
   private $data;
   private $secret;

   public function __wakeup() {
       $this->secret = '123456';
   }
}

3. 如何使用序列化与外部服务通信

要使用序列化与外部服务通信,可以使用 PHP 的内置函数来发送 HTTP 请求,例如file_get_contents()curl_exec(),然后你可以将序列化数据作为请求中的参数传递,外部服务可以在其端反序列化数据以访问信息。

下面是使用序列化将数据发送到外部服务的示例:

$data = [
   "name" => "John",
   "age" => 30
];

// Serialize the data
$serializedData = serialize($data);

// Send the serialized data to the external service using HTTP POST
$ch = curl_init("http://example.com/service");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "data=" . $serializedData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

// Handle the response from the service
echo $response;

在外部服务上,您可以使用该unserialize()函数将序列化数据转换回 PHP 数据结构或对象。

// Get the serialized data from the HTTP POST request
$serializedData = $_POST['data'];

// Unserialize the data
$data = unserialize($serializedData);

// Use the data
echo "Name: " . $data['name'] . "\n";
echo "Age: " . $data['age'] . "\n";

4. 序列化实例 - Laravel Queue

当 Laravel 将 Job 类存储到队列服务(可以是 Redis、AWS SQS 或类似的服务)中时,对象被序列化。当你在 Laravel 中创建一个新的 Job 类时,它附带了 SerializesModels 特性。

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;

class ExampleJob implements ShouldQueue
{
   use Dispatchable;
   use InteractsWithQueue;
   use Queueable;
   use SerializesModels;

   /**
    * Create a new job instance.
    *
    * @return void
    */
   public function __construct()
   {
       //
   }

   /**
    * Execute the job.
    *
    * @return void
    */
   public function handle()
   {
       //
   }
}

如果你的作业类包含对 Eloquent 模型的引用,这个特性允许你自定义序列化过程。它包含上面看到的钩子的实现:

namespace Illuminate\Queue;

trait SerializesModels
{
   use SerializesAndRestoresModelIdentifiers;

   /**
    * Prepare the instance for serialization.
    *
    * @return array
    */
   public function __sleep()
   {
       // ...
   }

   /**
    * Restore the model after serialization.
    *
    * @return void
    */
   public function __wakeup()
   {
       // ...
   }

   /**
    * Prepare the instance values for serialization.
    *
    * @return array
    */
   public function __serialize()
   {
       // ...
   }

   /**
    * Restore the model after serialization.
    *
    * @param  array  $values
    * @return void
    */
   public function __unserialize(array $values)
   {
       // ...
   }
}

如Laravel 文档中所述:

如果你的排队作业在其构造函数中接受 Eloquent 模型,则只有模型的标识符将被序列化到队列中。当实际处理作业时,队列系统将自动从数据库中重新检索完整的模型实例及其加载的关系。这种模型序列化方法允许将更小的作业有效负载发送到您的队列驱动程序。

5. 最后

serialize()并且unserialize() 是 PHP 的默认序列化技术。事实上,其他编程语言中有许多库允许你根据 PHP 标准序列化对象和数据结构,例如 Java 中的这个库:

github.com/marcospassos/java-php-serializer

除了这种特定格式,您还可以使用 JSON 标准将数据传输到外部服务。PHP 通过两个函数支持这种序列化:json_encodejson_decode

来源:https://juejin.cn/post/7222874734186692645

标签:PHP,序列化
0
投稿

猜你喜欢

  • 如何在2003系统注册fso组件

    2010-11-29 19:55:00
  • ASP程序种如何调用DLL文件

    2008-01-15 19:12:00
  • sqlserver中根据字符分割字符串的最好的写法分享

    2012-06-06 19:44:40
  • z-blog文章摘要图文混排

    2009-02-28 13:49:00
  • 配置SQL Server文件组对应不同的RAID系统

    2009-01-04 14:31:00
  • 电子商务搜索LIST页面用户体验设计

    2010-08-03 12:57:00
  • js倒记时代码,自定义时间改变时间,日期到时事件,日期格式。

    2010-08-08 08:51:00
  • MySQL Order By语法

    2011-01-04 19:58:00
  • JavaScript开发时的五个小提示

    2007-11-21 19:54:00
  • sql之IN和BETWEEN条件运算

    2007-09-11 13:35:00
  • 用javascript 转换外部链接样式

    2007-09-17 10:48:00
  • sqlserver 数据库压缩与数据库日志(ldf)压缩方法分享

    2012-01-05 18:57:19
  • SQL学习笔记三 select语句的各种形式小结

    2011-09-30 11:09:31
  • MySQL常见错误提示及解决方法

    2008-02-23 10:08:00
  • asp解决防止表单重复提交的方法

    2007-10-19 18:40:00
  • javaScript通用数据类型校验函数

    2009-07-06 12:49:00
  • 用户体验设计答疑对话(半吊子和纯外行)

    2010-11-30 21:27:00
  • 利用aspjpeg组件自动生成产品缩略图asp源代码

    2007-08-10 10:14:00
  • phpstudy apache开启ssi使用详解

    2023-05-25 08:04:44
  • 网页打开速度的心理学

    2009-03-26 13:18:00
  • asp之家 网络编程 m.aspxhome.com