Liên hệ
spl

Các giao diện và lớp mẫu đã định nghĩa của PHP SPL

Tìm hiểu giao diện và lớp định nghĩa sẵn gồm Countable, Traversable, Iterator, IteratorAggregate, ArrayAccess, Serializable, Closure

Các giao diện của SPL

Các giao diễn mẫu này là chuẩn xây dựng lên các lớp để sử dụng cho các lớp triển khai SPL.

Giao diện Countable

Countable {
abstract public int count ( void )
}

Giao diện này để xây dựng lớp có thể đểm các phần tử chứa trong nó. Ví dụ:

class Products implements Countable
{
    private $_totals;

    public function __construct($_totals)
    {
        $this->_totals = $_totals;
    }

    public function count()
    {
        return $this->_totals;
    }
}

$products = new Products(10);
echo $products->count();

Giao diện Traversable

Traversable {
}

Giao diện này không có hàm nào cả, khi triển khai một lớp theo giao diện này đơn gian là cho biết lớp có thể duyệt các phẩn tử trong nó bằng lệnh foreach.

class Products implements Traversable {
    //.... your code
}

$prducts = new Products();
if ($prducts instanceof Traversable)
    echo 'Dùng được lệnh để duyệt phần tử';
else
    echo 'không dùng được lệnh foreach';

Giao diện Iterator

Iterator extends Traversable {
abstract public mixed current ( void )
abstract public scalar key ( void )
abstract public void next ( void )
abstract public void rewind ( void )
abstract public boolean valid ( void )
}

Giao diện Iterator là mẫu để xây dựng lên danh sách, triển khai giao diện này bạn cần định nghĩa các hàm theo đúng ý nghĩa của nó như sau:

  • current() : trả về phần tử hiện tại.
  • key(): trả về key của phần tử hiện tại (key do bạn tự xây dựng như: index trong mảng, mãy id sản phẩm ...)
  • next(): trả về phần tử tiếp theo.
  • rewind(): quay trở lại phần tử đầu tiên khi duyệt danh sách.
  • valid(): kiểm tra xem vị trí hiện tại (key hiện tại có hợp lệ).

iterator

Ví dụ:

<?php

class Products implements Iterator {
    private $product = [
        'Phone A',
        'Phone B',
        'Phone C'
    ];
    private $_currenproduct = 0;

    public function current()
    {
       echo 'Call:'.__METHOD__, PHP_EOL;
       return $this->product[$this->_currenproduct];
    }


    public function next()
    {
        echo 'Call:'.__METHOD__, PHP_EOL;
        $this->_currenproduct++;
    }

    public function key()
    {
        echo 'Call:'.__METHOD__, PHP_EOL;
        return $this->_currenproduct;
    }

    public function valid()
    {
        echo 'Call:'.__METHOD__, PHP_EOL;
        return isset($this->product[$this->_currenproduct]);
    }


    public function rewind()
    {
        echo 'Call:'.__METHOD__, PHP_EOL;
        $this->_currenproduct = 0;
    }
}


$products = new Products();
foreach ($products as $key => $product) {
    echo "\t\tResult:".$key, '=>', $product, PHP_EOL; 
}

Chạy mã trên ra kết quả:

Call:Products::rewind
Call:Products::valid
Call:Products::current
Call:Products::key
        Result:0=>Phone A
Call:Products::next
Call:Products::valid
Call:Products::current
Call:Products::key
        Result:1=>Phone B
Call:Products::next
Call:Products::valid
Call:Products::current
Call:Products::key
        Result:2=>Phone C
Call:Products::next
Call:Products::valid

Giao diện RecursiveIterator

RecursiveIterator extends Iterator {
/* Methods */
public RecursiveIterator getChildren ( void )
public bool hasChildren ( void )
/* Inherited methods */
abstract public mixed Iterator::current ( void )
abstract public scalar Iterator::key ( void )
abstract public void Iterator::next ( void )
abstract public void Iterator::rewind ( void )
abstract public boolean Iterator::valid ( void )
}

Giao diện này kế thừa giao diện Iterator, nên ngoài các hàm từ Iterator phải định nghĩa có thêm hai hàm getChildren và hasChildrend.

  • getChildren(): Trả về phần tử được hiểu là phần tử con.
  • hasChildren() : kiểm tra phần tử có phần tử con không

recursiveiterator

Việc sử dụng giao diện này để xây dựng lên các cấu trúc dữ liệu dạng cây (Tree), dễ dàng đệ quy đến các nhánh. Ví dụ:

<?php

class Products implements RecursiveIterator {

    private $product_child = null;
    private $product = [];
    private $_currenproduct = 0;
    private $nameproduct;

    /**
     * @return mixed
     */
    public function getNameproduct()
    {
        return $this->nameproduct;
    }

    /**
     * Products constructor.
     * @param $nameproduct
     */
    public function __construct($nameproduct)
    {
        $this->nameproduct = $nameproduct;
    }


    public function current()
    {

       return $this->product[$this->_currenproduct];
    }


    public function next()
    {

        $this->_currenproduct++;
    }

    public function key()
    {

        return $this->_currenproduct;
    }

    public function valid()
    {

        return isset($this->product[$this->_currenproduct]);
    }


    public function rewind()
    {

        $this->_currenproduct = 0;
    }

    public function hasChildren()
    {
        return ($this->product_child != null);
    }


    public function getChildren()
    {
       return $this->product_child;
    }


    public function setProductChild($product_child)
    {
        $this->product_child = $product_child;
    }

    public function addProduct($pro) {
        $this->product[] = $pro;
    }


}

function printproduct($products, $level) {

    echo $level.$products->getNameproduct(), PHP_EOL;
    foreach ($products as $product)
    {
        printproduct($product, $level.'----');
        if ($product->hasChildren())
            printproduct($product->getChildren(), $level.'--------');
    }
 
}


$products = new Products('Tổng kho');

$dienthoai = new Products('Điện thoại');

$dienthoaidanhsach = new Products('Danh sách điện thoại');

$iphone = new Products('Iphone');
$iphone->addProduct(new Products('Iphone1'));
$iphone->addProduct(new Products('Iphone2'));
$iphone->addProduct(new Products('Iphone3'));

$dienthoaidanhsach->addProduct($iphone);
$dienthoaidanhsach->addProduct(new Products('Nokia'));
$dienthoaidanhsach->addProduct(new Products('Samsung'));
$dienthoai->setProductChild($dienthoaidanhsach);

$products->addProduct($dienthoai);
$products->addProduct(new Products('Tủ lạnh'));
$products->addProduct(new Products('Máy giặt'));

$level = "";
printproduct($products,$level);

Chạy code trên ra kết quả sau:

Tổng kho
----Điện thoại
--------Danh sách điện thoại
------------Iphone
----------------Iphone1
----------------Iphone2
----------------Iphone3
------------Nokia
------------Samsung
----Tủ lạnh
----Máy giặt

Giao diện OuterIterator

OuterIterator extends Iterator {
/* Methods */
public Iterator getInnerIterator ( void )
/* Inherited methods */
abstract public mixed Iterator::current ( void )
abstract public scalar Iterator::key ( void )
abstract public void Iterator::next ( void )
abstract public void Iterator::rewind ( void )
abstract public boolean Iterator::valid ( void )
}

Giao diện IteratorAggregate

Dùng để xây dựng lớp tập hợp, cho duyệt qua các phần tử. Giao diện đó như sau:

IteratorAggregate extends Traversable {
 abstract public Traversable getIterator ( void )
}

Đơn giản, lớp xây dựng từ giao diện này, thì khi gọi hàm foreach nó sẽ gọi getIterator để lấy đối tượng cho duyệt.

Ví dụ:

<?php
class myData implements IteratorAggregate {
    public $property1 = "Public property one";
    public $property2 = "Public property two";
    public $property3 = "Public property three";

    public function __construct() {
        $this->property4 = "last property";
    }
    //Hàm này được gọi và trả về giá trị cho lệnh foreach khi bắt đầu được gọi
    public function getIterator() {
        return new ArrayIterator($this);
    }
}

$obj = new myData;

foreach($obj as $key => $value) {
    var_dump($key, $value);
    echo "\n";
}
?>

Giao diện ArrayAccess 

ArrayAccess {
/* Methods */
abstract public boolean offsetExists ( mixed $offset )// gọi khi gọi hàm isset([])
abstract public mixed offsetGet ( mixed $offset )//Toán tử lấy giá trị []
abstract public void offsetSet ( mixed $offset , mixed $value ) //Toán tử gán giá trị []
abstract public void offsetUnset ( mixed $offset ) // Gọi khi gọi hàm unset([])
}

Giao diện này cho bạn xây dựng ra các đối tượng mà truy cập vào nó giống như mảng.

Ví dụ:

<?php
class obj implements ArrayAccess {
    private $container = array();

    public function __construct() {
        $this->container = array(
            "one"   => 1,
            "two"   => 2,
            "three" => 3,
        );
    }

    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    public function offsetExists($offset) {
        return isset($this->container[$offset]);
    }

    public function offsetUnset($offset) {
        unset($this->container[$offset]);
    }

    public function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
}

$obj = new obj;

var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset($obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);
?>

Giao diện Serializable

Serializable {
/* Methods */
abstract public string serialize ( void )
abstract public void unserialize ( string $serialized )
}

Giao diện này giúp bạn xây dựng một lớp có chức năng serialzable dữ liệu. 

Serialize có nghĩa là sắp theo thứ tự dữ liệu thường với mục đích lưu trữ trên đĩa, vào database ... Sắp xếp dữ liệu theo thứ tự nghĩa là đặt ra một qua tắc riêng sắp xếp dữ liệu đối tượng để lưu trên đĩa, sau đó dựa theo quy tắc này để phục hồi thành đối tượng để sử dụng.

Khi một lớp bạn xây dựng từ giao diện Serializable, thì bạn có thể gọi hai hàm PHP thông dụng là serialize unserialize.

<?php
class obj implements Serializable {
    private $data;
    public function __construct() {
        $this->data = "My private data";
    }
    public function serialize() {
        return serialize($this->data);
    }
    public function unserialize($data) {
        $this->data = unserialize($data);
    }
    public function getData() {
        return $this->data;
    }
}

$obj = new obj;
$ser = serialize($obj);

var_dump($ser);

$newobj = unserialize($ser);

var_dump($newobj->getData());
?>

 

 

 

 

 

 

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