Liên hệ
zend framework

Biến đối tượng thành mảng và ngược lại với zend-hydrator

Cách sử dụng zend-hydrator để biến một đối tượng PHP thành mảng và ngược lại chuyển mảng thành đối tượng của một lớp nào đó

Giới thiệu zend-hydrator

Hydration là hành động biến đổi qua lại giữa đối tượng từ tập hợp dữ liệu. Với zend-hydrator cung cấp cả cơ chế chuyển đổi đối tượng và trích xuất dữ liệu từ đối tượng.

Để cài đặt riêng zend-hydrator vào ứng dụng của bạn, hãy chạy lệnh composer trong thư mục chứa ứng dụng

$ composer require zendframework/zend-hydrator

Hoặc tải về và tích hợp thủ công từ zend-hydrator.

Các Interface cơ sở để xây dựng lên zend-hydrator

Các interface gồm: ExtractionInterface, HydrationInterface, HydratorInterface

namespace Zend\Hydrator;

interface ExtractionInterface
{
    /
     * Extract values from an object
     *
     * @param  object $object
     * @return array
     */
    public function extract($object);
}
namespace Zend\Hydrator;

interface HydrationInterface
{
    /
     * Hydrate $object with the provided $data.
     *
     * @param  array $data
     * @param  object $object
     * @return object
     */
    public function hydrate(array $data, $object);
}

namespace Zend\Hydrator;

interface HydratorInterface extends
    ExtractionInterface,
    HydrationInterface
{
}

Từ các giao diện này ZF triển khai thành các lớp mà bạn có thể sẽ muốn dùng tới như : ArraySerializableClassMethodsDelegatingHydratorObjectProperty,  Reflection.

ArraySerializable

Đây là lớp triên khai đơn giản, dùng để cập nhật mảng dữ liệu vào đối tượng và trích xuất dữ liệu từ đối tượng thông qua hai phương thức là hydrate(array $data, $object) và extract($object).

Để sử dụng nó, các lớp mà bạn xây dựng tạo ra đối tượng cần định nghĩa các phương thức như sau:

  • Để cập nhật được dữ liệu cần xây dựng một trong hai hàm có tên exchangeArray($ar) hoặc populate($ar).
  • Để trích xuất được dữ liệu cần xây dựng hàm getArrayCopy().

Ví dụ: tạo file php arrayserializable.php, định nghĩa lớp Student rồi dùng ArraySerializable để cập nhật và trích xuất dữ liệu:

<?php

include "vendor/autoload.php";

use Zend\Hydrator;

//Định nghĩa lớp Student

class Student {

    protected $name;
    protected $yearobirth;
    protected $class;
    protected $gen;

    
    public function exchangeArray($ar) //Tên hàm có thể đổi là populate
    {

        $this->name = $ar['name'];
        $this->yearobirth = $ar['yearobirth'];
        $this->class = $ar['class'];
        $this->gen = $ar['gen'];
    }

    
    public function getArrayCopy()
    {
        return [
            'name' => $this->name,
            'yearobirth' => $this->yearobirth,
            'class' => $this->class,
            'gen' => $this->gen
        ];
    }

}


$studendata = [
    'name' => 'Nguyen Van A',
    'yearobirth' => 2000,
    'class' => 'A1',
    'gen' => 1
];

$sinhvienA = new Student();


$hydrator = new Hydrator\ArraySerializable();

//Đưa dữ liệu vào đối tượng
$hydrator->hydrate($studendata, $sinhvienA);

var_dump($sinhvienA);

// Trích xuất dữ liệu từ đối tượng
$data = $hydrator->extract($sinhvienA);

var_dump($data);

ClassMethods

Với lớp triển khai này thì việc thực hiện hydrate và extract lại thông qua các hàm setter và getter của lớp định nghĩa. Khi hydrate thì nó sẽ tìm các hàm setter tương ứng với tên của index dữ liệu và khi extract nó sẽ tìm các hàm setter để trích xuất dữ liệu. 

Ví dụ, copy file arrayserializable.php ở trên thành file classmethods.php và cập nhật như sau để sử dụng ClassMethods.

<?php

include "vendor/autoload.php";

use Zend\Hydrator;

//Định nghĩa lớp Student

class Student {

    protected $name;
    protected $yearobirth;
    protected $class;
    protected $gen;


    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getYearobirth()
    {
        return $this->yearobirth;
    }

    public function setYearobirth($yearobirth)
    {
        $this->yearobirth = $yearobirth;
    }

    public function getClass()
    {
        return $this->class;
    }

    public function setClass($class)
    {
        $this->class = $class;
    }

    public function getGen()
    {
        return $this->gen;
    }

    public function setGen($gen)
    {
        $this->gen = $gen;
    }

}


$studendata = [
    'name' => 'Nguyen Van A',
    'yearobirth' => 2000,
    'class' => 'A1',
    'gen' => 1
];

$sinhvienA = new Student();


$hydrator = new Hydrator\ClassMethods();

//Đưa dữ liệu vào đối tượng
$hydrator->hydrate($studendata, $sinhvienA);

var_dump($sinhvienA);

// Trích xuất dữ liệu từ đối tượng
$data = $hydrator->extract($sinhvienA);

var_dump($data);

DelegatingHydrator

Lớp này sẽ sử dụng HydratorPluginManager để xác định loại Hydrator cho từng đối tượng rồi tiến hành hydrate hay extract. Diễn giải hoạt động ứng dụng như sau:

  • Giả sử bạn có một số Hydrator mỗi Hydrator đó ứng dụng cho một loại lớp cụ thể ví dụ $albumHydrator dùng để hydrate và extract với các đối tượng sinh ra từ lớp Album. $artistHydrator dùng để hydrate và extract với các đối tượng sinh ra từ lớp Artist.
  • Bạn vẫn định nghĩa lớp Album và Artist, cũng như tạo $albumHydrator, $artistHydrator theo cách trên. Sau đó tạo ra đối tượng HydratorPluginManager và dùng hàm setService của nó để tập hợp tất cả các Hydrator này vào.
  • Tiếp theo tạo ra đối tượng DelegatingHydrator và chỉ ra nó sẽ dùng HydratorPluginManager do bạn tạo ra.
  • Cuối cùng để hydrate và extract dùng DelegatingHydrator sẽ tự động xác định cái Hydrator nào thông qua loại đối tượng.

Ví dụ:

// Tạo các đối tượng Hydrator
$albumHydrator = new Zend\Hydrator\ClassMethods;
$artistHydrator = new Zend\Hydrator\ClassMethods;

// Đưa các Hydrator vào một tập hơp.
$hydrators = new Zend\Hydrator\HydratorPluginManager;
$hydrators->setService('Album', $albumHydrator);  //Tự động dùng $albumHydrator nếu tham số truyền vào từ lớp Album
$hydrators->setService('Artist', $artistHydrator); 

$delegating = new Zend\Hydrator\DelegatingHydrator($hydrators);

$array = $delegating->extract(new Artist);         //$delegating sẽ tự biết dùng $artistHydrator
$artist = $delegating->hydrate($data, new Artist); 

ObjectProperty

Với lớp này thì việc hydrate và extract sẽ tự động sử dụng các thuộc tính public.

<?php

include "vendor/autoload.php";

use Zend\Hydrator;

//Định nghĩa lớp Student

class Student {

    public $name;
    public $yearobirth;
    public $class;
    public $gen;


}


$studendata = [
    'name' => 'Nguyen Van A',
    'yearobirth' => 2000,
    'class' => 'A1',
    'gen' => 1
];

$sinhvienA = new Student();


$hydrator = new Hydrator\ObjectProperty();

//Đưa dữ liệu vào đối tượng
$hydrator->hydrate($studendata, $sinhvienA);

var_dump($sinhvienA);

// Trích xuất dữ liệu từ đối tượng
$data = $hydrator->extract($sinhvienA);

var_dump($data);

Reflection

Tương tự như ObjectProperty nhưng lớp này sử dụng API reflection của PHP để xác định các thuộc tính public.

 

 

Vui lòng đăng ký ủng hộ kênh