PHP Predefined Interfaces 預定義介面
SPL提供了6個迭代器介面:
Traversable |
遍歷介面(檢測一個類是否可以使用 foreach 進行遍歷的介面) |
---|---|
Iterator |
迭代器介面(可在內部迭代自己的外部迭代器或類的介面) |
IteratorAggregate |
聚合式迭代器介面(建立外部迭代器的介面) |
OuterIterator |
迭代器巢狀介面(將一個或多個迭代器包裹在另一個迭代器中) |
RecursiveIterator |
遞迴迭代訪問介面(提供遞迴訪問功能) |
SeekableIterator |
可索引迭代訪問介面(實現查詢功能) |
下面對各種迭代器介面簡單介紹一下:
1. Traversable
Traversable介面實際上不是一個介面,在實際寫php程式碼中不能用。因為只有內部的PHP類(用C寫的類)才可以直接實現 Traversable介面。可以說這是個特性級別的東西。實際的PHP程式設計中我們使用Iterator介面或者IteratorAggregate介面 來實現遍歷。
Traversable {
}
Traversable 介面不能直接實現(implements).Traversable 重要的一個用處就是判斷一個類是否可以遍歷:
if($class instanceof Traversable)
{
//foreach...
}
下面是官方例子:
<?php
if( !is_array( $items ) && !$items instanceof Traversable )
//Throw exception here
?>
2. Iterator
Iterator介面的主要用途是允許一個類實現一個基本的迭代功能,從而使它可以被迴圈訪問,根據鍵值訪問以及回滾。Iterator介面摘要如下:
Iterator extends Traversable { //返回當前索引遊標指向的元素 abstract public mixed current(void) //返回當前索引遊標指向的元素的鍵名 abstract public scalar key(void) //移動當前索引遊標指向下一元素 abstract public void next(void) //重置索引遊標的指向第一個元素 abstract public void rewind(void) //判斷當前索引遊標指向的是否是一個元素,常常在呼叫 rewind()或 next()使用 abstract public boolean valid(void) }
外部迭代器介面,實現該介面的物件可以迭代自己內部的資料。
Iterator 的例子這裡就不再列舉了,本專題前面部分以後後續有很多例子,具體請自行檢視。
3. IteratorAggregate
又叫聚合式迭代器。建立外部迭代器的介面,其摘要如下:
IteratorAggregate extends Traversable {
//實現該方法時,必須返回一個實現了Iterator介面的類的例項
abstract public Traversable getIterator ( void )
}
其中getIterator 方法返回值必須是能遍歷或實現Iterator介面(must be traversable or implement interface Iterator)。SPL還提供了一些專門用來與IteratorAggregate介面一起使用的內建迭代器。使用這些迭代器意味著只需要實現一個方 法並例項化一個類就可以使物件可以迭代訪問了。
例項:
/**
* @author 簡明現代魔法 http://www.nowamagic.net
*/
class myData implements IteratorAggregate
{
public $property1 = "公共屬性1";
public $property2 = "公共屬性2";
public $property3 = "公共屬性3";
public function __construct()
{
$this->property4 = "最後一個公共屬性";
}
public function getIterator()
{
return new ArrayIterator($this);
}
}
$obj = new myData;
foreach ($obj as $key => $value) {
echo "鍵名:{$key} 值:{$value}n";
}
程式輸出:
鍵名:property1 值:公共屬性1
鍵名:property2 值:公共屬性2
鍵名:property3 值:公共屬性3
鍵名:property4 值:最後一個公共屬性
4. ArrayAccess
陣列式訪問介面。實現該介面的物件能像陣列一樣使用:
ArrayAccess {
/* Methods */
abstract public boolean offsetExists ( mixed $offset )
abstract public mixed offsetGet ( mixed $offset )
abstract public void offsetSet ( mixed $offset , mixed $value )
abstract public void offsetUnset ( mixed $offset )
}
- ArrayAccess::offsetExists — 檢查一個偏移位置是否存在
- ArrayAccess::offsetGet — 獲取一個偏移位置的值
- ArrayAccess::offsetSet — 設定一個偏移位置的值
- ArrayAccess::offsetUnset — 復位一個偏移位置的值
舉個栗子:
/**
* @author 簡明現代魔法 http://www.nowamagic.net
*/
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);
5. Serializable
序列化介面。實現該介面的類不能使用__sleep() 和__wakeup().在serialize時不執行__destruct(),在unserialize不執行__construct()。
Serializable {
/* Methods */
abstract public string serialize ( void )
abstract public mixed unserialize ( string $serialized )
}
實現此介面的類將不再支援 __sleep() 和 __wakeup()。不論何時,只要有例項需要被序列化,serialize 方法都將被呼叫。它將不會呼叫 __destruct() 或有其他影響,除非程式化地呼叫此方法。當資料被反序列化時,類將被感知並且呼叫合適的 unserialize() 方法而不是呼叫 __construct()。如果需要執行標準的構造器,你應該在這個方法中進行處理。
- Serializable::serialize — 物件的字串表示
- Serializable::unserialize — 構造物件
Serializable {
/* Methods */
abstract public string serialize ( void )
abstract public mixed unserialize ( string $serialized )
}
例子:
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);
$newobj = unserialize($ser);
var_dump($newobj->getData());
6. Closure
Closure {
/* 方法 */
__construct ( void )
public static Closure bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )
public Closure bindTo ( object $newthis [, mixed $newscope = 'static' ] )
}
這個具體還沒研究,具體可以去看官方文件:http://www.php.net/manual/en/reserved.interfaces.php