Các giao diện mẫu định nghĩa sẵn trong thư viện SPL này dùng để xây dựng lên các lớp SPL.
Giao diện Countable
Giao diện này được định nghĩa như sau:
Countable { /* Methods */ abstract public count ( void ) : int }
Sử dụng giao này dùng để triển khai các lớp có chứa các phân tử, nó cung cấp hàm trả về số lượng các phần
tử counnt()
. 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
Giao diện Iterator
triển khai từ giao diện Traversable
Iterator extends Traversable { /* Methods */ abstract public current ( void ) : mixed abstract public key ( void ) : scalar abstract public next ( void ) : void abstract public rewind ( void ) : void abstract public valid ( void ) : bool }
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ệ).
Giao diện này là triển khai cấu trúc dữ liệu danh sách, danh sách liên kết. Ví dụ danh sách liên kết sau có 5 phần tử
Ví dụ:
<?php /*** * Lớp danh sách 3 sản phẩm liên kết với nhau */ class Products implements Iterator { // Định nghĩa mảng lưu các phần tử private $product = [ 'Phone A', 'Phone B', 'Phone C' ]; // Vị trí phần tử hiện tại private $_currenproduct = 0; // Lấy phần tử hiện tại public function current() { echo 'Call:'.__METHOD__, PHP_EOL; return $this->product[$this->_currenproduct]; } // Dịch chuyển đến phần tử tiếp theo public function next() { echo 'Call:'.__METHOD__, PHP_EOL; $this->_currenproduct++; } // Key (định danh) của phần tử hiện tại public function key() { echo 'Call:'.__METHOD__, PHP_EOL; return $this->_currenproduct; } // Kiểm tra hợp lệ Vị trí (index) hiện tại public function valid() { echo 'Call:'.__METHOD__, PHP_EOL; return isset($this->product[$this->_currenproduct]); } // Khởi tạo lại vòng lặp (quay trở lại vị trí phần tử đầu tiên) public function rewind() { echo 'Call:'.__METHOD__, PHP_EOL; $this->_currenproduct = 0; } } // Chạy thử $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
Giao diện này được định nghĩa như sau:
RecursiveIterator extends Iterator { /* Methods */ public getChildren ( void ) : RecursiveIterator public hasChildren ( void ) : bool /* Các phương thức kế thừa từ Iterator */ abstract public Iterator::current ( void ) : mixed abstract public Iterator::key ( void ) : scalar abstract public Iterator::next ( void ) : void abstract public Iterator::rewind ( void ) : void abstract public Iterator::valid ( void ) : bool }
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
Giao diện này là triển khai cấu trúc dữ liệu cây - tree
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 - cây nhiều cấp */ class Products implements RecursiveIterator { /*** * @var string - tên sản phẩm */ private $nameproduct; /*** * @var array - mảng các sản phẩm */ private $product = []; /*** * @var int index sản phẩm hiện tại */ private $_currenproduct = 0; /*** * @var Products các sản phẩm con */ private $product_child = null; /*** * @return string */ public function getNameproduct() { return $this->nameproduct; } /*** * Products constructor. * @param $nameproduct string - tên sản phẩm khởi tạo */ 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; } /*** * @return bool - kiểm tra có sản phẩm con */ public function hasChildren() { return ($this->product_child != null); } /*** * @return Products|RecursiveIterator|null - trả về sản phẩm con */ public function getChildren() { return $this->product_child; } /*** * @param $product_child - thiết lập sản phẩm con */ public function setProductChild($product_child) { $this->product_child = $product_child; } /*** * @param $pro - thêm sản phẩm vào dannh sách */ 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 getInnerIterator ( void ) : Iterator /* Inherited methods */ abstract public Iterator::current ( void ) : mixed abstract public Iterator::key ( void ) : scalar abstract public Iterator::next ( void ) : void abstract public Iterator::rewind ( void ) : void abstract public Iterator::valid ( void ) : bool }
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
và 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()); ?>