一文帶你吃透什么是PHP中的序列化
目錄
- 1. php 中的序列化
- 2. 序列化和反序列化過程中的鉤子
- 3. 如何使用序列化與外部服務通信
- 4. 序列化實例 - Laravel Queue
- 5. 最后
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 中的這個庫:
除了這種特定格式,您還可以使用 JSON 標準將數據傳輸到外部服務。PHP 通過兩個函數支持這種序列化:json_encode
和json_decode
。
到此這篇關于一文帶你吃透什么是PHP中的序列化的文章就介紹到這了,更多相關PHP序列化內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!
