Hàm serialize và unserialize - lưu trữ và phục hồi giá trị

Hàm serialize() được dùng để phát sinh một chuỗi (các byte) của một giá trị (đối tượng), với mục đích có thể lưu trữ chuỗi này dễ dàng (trong database, trong file, hoạc trao đổi giữa các thành phần). Từ chuỗi này có thể phục hồi nó về giá trị bạn đầu (kể cả phục hồi đối tượng) bằng hàm unserialize(). Ví dụ, để lưu trữ dữ liệu là một mảng - thì sẽ phát sinh một chuỗi (các byte) bằng serialize(), chuỗi này sẽ lưu trữ lại, từ chuỗi này có thể phục hồi về giá trị ban đầu bằng hàm unserialize()

Cú pháp:

// $value có thể có kiểu bất kỳ trừ resource và một số đối tượng
$string_bytes =  serialize($value);

// Phục hồi lại $value từ chuỗi byte lưu trữ
$value = unserialize($string_bytes);

Ví dụ trả về từ serialize trên một số loại dữ liệu:

var_export(serialize(123));              // 'i:123;'
var_export(serialize(1.123));            // ''d:1.123;'
var_export(serialize(true));             // 'b:1;'
var_export(serialize('XUANTHULAB'));     // 's:10:"XUANTHULAB";'
var_export(serialize(['a','x' => 'X'])); // 'a:2:{i:0;s:1:"a";s:1:"x";s:1:"X";}'

Hàm serializeunserialize có thể áp dụng cho các đối tượng lớp, ví dụ:

// MỘT ĐỐI TƯỢNG MỚI
$obj = new stdClass();
$obj->data0 = 'XUANTHULAB';
$obj->data1 = [1,2,3];
var_dump($obj);
/*
 object(stdClass)[503]
  public 'data0' => string 'XUANTHULAB' (length=10)
  public 'data1' =>
    array (size=3)
      0 => int 1
      1 => int 2
      2 => int 3
 */

// PHÁT SINH CHUỖI LƯU TRỮ
$serialize_string = serialize($obj);
var_dump($serialize_string);
/*
 string 'O:8:"stdClass":2:{s:5:"data0";s:10:"XUANTHULAB";s:5:"data1";a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}}' (length=91)
*/


// PHỤC HỒI ĐỐI TƯỢNG
$newOb = unserialize($serialize_string);
var_dump($newOb);
/*
object(stdClass)[507]
  public 'data0' => string 'XUANTHULAB' (length=10)
  public 'data1' =>
    array (size=3)
      0 => int 1
      1 => int 2
      2 => int 3
 */

Phương thức magic __serialize() và _unserialize()

Nếu lớp của bạn tự xây dựng, không có hai phương thức này thì thì bạn vẫn có thể dùng hàm serializeunserialize một cách bình thường. Nếu bạn muốn tùy biến tác vụ này, thì cho vào lớp hai phương thức: __serialize và _unserialize với cú pháp:

// Phương thức này tự gọi khi hàm serialize gọi
// Bạn cần trả về một mảng, cấu trúc thế nào do bạn thiết kế = để sau này chính bạn
// sử dụng trong __unserialize phục hồi đối tượng
public __serialize() : array
{
    // phải trả về một mảng
}

// Tự gọi khi hàm unserialize chạy
// Nhận tham số là mảng dữ liệu mà __serialize trả về, bạn dùng
// dữ liệu mảng đó để phục hồi dữ liệu của đối tượng
public __unserialize(array $data) : void
{

}

Ví dụ:

class User
{
    private $name;
    private $age;
    public  $hash; // mỗi đới tướng lớp User có mã hask khác nhau

    public function __construct($name, $age)
    {
        $this->name = $name;
        $this->age  = $age;
        $this->hash = spl_object_hash($this);
    }


    public function __serialize(): array
    {
        return [
          'ten' => $this->name,
          'tuoi' => $this->age
        ];
    }

    public function __unserialize(array $data): void
    {
        $this->name = $data['ten'];
        $this->age = $data['tuoi'];
        $this->hash = spl_object_hash($this);
    }


}

// MỘT ĐỐI TƯỢNG USER BAN ĐẦU
$user = new User('XTL', 20);
var_dump($user);
/*
object(User)[494]
  private 'name' => string 'XTL' (length=3)
  private 'age' => int 20
  public 'hash' => string '000000005f06b7b2000000002092bd64' (length=32)
 */

// LẤY CHUỖI BYTES LƯU TRỮ (DO serialize trên mảng __serialize trả về)
$str_bytes = serialize($user);
var_dump($str_bytes);
/*
string 'O:4:"User":2:{s:3:"ten";s:3:"XTL";s:4:"tuoi";i:20;}' (length=51)
*/

// PHỤC HỒI, do __unserialize xử lý
$restore_user = unserialize($str_bytes);
var_dump($restore_user);
/*
object(User)[498]
  private 'name' => string 'XTL' (length=3)
  private 'age' => int 20
  public 'hash' => string '0000000076536d370000000070a8c4bb' (length=32)
 */

Đăng ký nhận bài viết mới