亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

自定義PHP數組類的實現

2019-11-08 03:12:32
字體:
來源:轉載
供稿:網友

php一開始是面向過程的語言,到后期才支持面向對象,數組在php中的類型是 “array”:

echo gettype(array());

輸出

array

很多操作數組的函數都是以 “array” 開頭,第一個參數為要操作的數組。

要實現一個數組類,需要實現Arrayaccess這個接口,這個接口的功能是 “提供像訪問數組一樣訪問對象的能力” ,該接口有四個方法:

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 )

這四個函數的作用如下(假設$obj是一個實現了該接口的類的實例):

offsetExists, 執行isset( $obj[$key])時觸發offsetGe,獲取$obj[$key]時觸發offsetSet, 執行 $obj[$key] = $value時觸發offsetUnset, 執行unset($obj[$key])時觸發

看上去有點類似C++的運算符重載。我們可以封裝一個類,以一個數組變量作為其私有屬性,這四個函數操作數組變量就行。

且看代碼: 我們把這個類命名為XArray。

class XArray implements ArrayAccess{ PRivate $container = array(); public function __construct($size = 0, $value = 0) { if ($size > 0) { $this->container = array_fill(0, $size, $value); } } public function offsetSet($offset, $value) { echo "call ", __METHOD__, PHP_EOL; if(is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; } } public function offsetUnset($offset) { echo "call ", __METHOD__, PHP_EOL; unset($this->container[$offset]); } public function offsetGet($offset) { echo "call ", __METHOD__, PHP_EOL; return isset($this->container[$offset]) ? $this->container[$offset] : null; } public function offsetExists($offset) { echo "call ", __METHOD__, PHP_EOL; return isset($this->container[$offset]); }}

測試:

$obj = new XArray(5, 10);$obj[] = 16;echo $obj['a'];isset($obj[3]);unset($obj['a']);

輸出:

call XArray::offsetSetcall XArray::offsetGetcall XArray::offsetExistscall XArray::offsetUnset

正如以上分析所言。

我們可以像操作數組一樣操作一個XArray類的實例,可是對于便利操作(foreach),就不行了。

foreach ($obj as $v) { echo $v;}

沒有輸出。

要能讓XArray的實例實現遍歷操作,得實現Traversable接口,但這是個抽象接口,不過Iterator接口繼承了Traversable接口,所以我們可以實現Iterator接口。這個接口有5個方法:

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 )

各方法的作用如下:

current, 返回當前元素key, 返回當前元素的鍵next, 移動到下一個元素rewind, 返回迭代器的第一個元素valid, 在rewind和next方法之后調用,檢查當前位置是否有效

在XArray中增加一個$position私有變量,然后增加以下5個方法:

public function rewind() { echo "call ", __METHOD__, PHP_EOL; reset($this->container); $this->position = 0; } public function current() { echo "call ", __METHOD__, PHP_EOL; return current($this->container); } public function next() { echo "call ", __METHOD__, PHP_EOL; next($this->container); $this->position++; } public function key() { echo "call ", __METHOD__, PHP_EOL; return key($this->container); } public function valid() { echo "call ", __METHOD__, PHP_EOL; return $this->position < count($this->container); }

有rewind, current,next,key這4個方法,內部都是通過調用php操作數組的相應方法來實現的。

測試:

$obj = new XArray();$obj[] = 1;$obj[] = 2;$obj[] = 3;foreach ($obj as $v) { echo $v, PHP_EOL;}

輸出:

call XArray::offsetSetcall XArray::offsetSetcall XArray::offsetSetcall XArray::rewindcall XArray::validcall XArray::current1call XArray::nextcall XArray::validcall XArray::current2call XArray::nextcall XArray::validcall XArray::current3call XArray::nextcall XArray::valid

由以上輸出可知,首次遍歷時,依次調用rewind, valid方法, 然后調用current方法得到值;后面都是依次調用next, valid方法,再調用current方法得到值。如果valid方法返回false,說明遍歷到了末尾,則不再調用current方法,遍歷結束。

可以看到,用 foreach($obj as $v)這種遍歷方式,并沒有調用key方法。

我們把遍歷方式改為foreach($obj as $k => $v)試一下:

$obj = new XArray();$obj[] = 1;$obj[] = 2;$obj[] = 3;foreach ($obj as $k => $v) { echo $v, PHP_EOL;}call XArray::offsetSetcall XArray::offsetSetcall XArray::offsetSetcall XArray::rewindcall XArray::validcall XArray::currentcall XArray::key1call XArray::nextcall XArray::validcall XArray::currentcall XArray::key2call XArray::nextcall XArray::validcall XArray::currentcall XArray::key3call XArray::nextcall XArray::valid

這次有調用key方法了,而且可以看到, key方法是在current方法調用之后才調用的。

這樣的數組類,功能還是有點弱,很多數組的方法都沒有,比如,push, pop, slice, 也不能獲取數組長度(length屬性)。

在XArray類中添加如下代碼:

public function all() { return $this->container; } /** $obj->length 獲取數組元素個數 */ public function __get($property) { if ($property == 'length') { return count($this->container); } return null; } /** 把一個XArray類的實例,數組或其他類型的變量合并到本實例的數組變量中 */ public function merge($data) { $class = get_class($this); if ($data instanceof $class) { $this->container = array_merge($this->container, $data->all()); } elseif (is_array($data)) { $this->container = array_merge($this->container, $data); } else{ $this->container[] = $data; } return $this; } public function shift() { return array_shift($this->container); } public function pop() { return array_pop($this->container); } public function push($ele) { foreach (func_get_args() as $v) { array_push($this->container, $v); } return $this; } public function unshift($ele) { foreach (func_get_args() as $v) { array_unshift($this->container, $v); } return $this; } public function slice($offset, $length) { $arr = array_slice($this->container, $offset, $length); if (empty($arr)) { return null; } $class = get_class($this); $obj = new $class(); return $obj->merge($arr); } /** 打印實例內容 */ public function dump() { echo "[elements begin]", PHP_EOL; foreach ($this->container as $k => $v) { echo "/t",$k, " => ", $v, PHP_EOL; } echo "[elements end]", PHP_EOL; }

大部分函數都是調用php的同名array_系列數組操作函數,其中unshift, push方法最后時return $this,可以實現鏈式調用, slice方法則是返回一個XArray對象。

測試代碼:

$obj = new XArray(2, 6);$obj[] = 16;$obj->push(1,2,3)->unshift(5)->pop();$obj->dump();echo "len(obj) = ", $obj->length, PHP_EOL;$obj2 = $obj->slice(0, 3);$obj2->dump();

輸出:

call XArray::offsetSet[elements begin] 0 => 5 1 => 6 2 => 6 3 => 16 4 => 1 5 => 2[elements end]len(obj) = 6[elements begin] 0 => 5 1 => 6 2 => 6[elements end]

如預期。

由于時間有限,數組操作的其他功能就不實現了。之前查看Laravel的源碼,有個文件也是實現了一個數組類,很多數組操作的方法都實現了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97福利一区二区| 国产精品视频白浆免费视频| 懂色av影视一区二区三区| 色悠悠久久88| 一区二区三区 在线观看视| 亚洲黄色有码视频| 欧美精品在线极品| 久久久久久亚洲精品不卡| 国产精品a久久久久久| 久久久久久久久久久国产| 国产精品嫩草影院久久久| 欧美激情videos| 美乳少妇欧美精品| 亚洲少妇中文在线| 懂色av一区二区三区| 日韩av在线最新| 亚洲肉体裸体xxxx137| 欧美午夜精品久久久久久浪潮| 成人福利在线观看| 日韩精品有码在线观看| 亚洲欧洲黄色网| 国产精品人成电影在线观看| 久久成年人免费电影| 91理论片午午论夜理片久久| 精品丝袜一区二区三区| 欧美精品videos另类日本| 九九热这里只有在线精品视| 亚洲国产黄色片| 中文字幕国产精品久久| 欧美日韩国产一区二区| 亚洲精品久久久久久下一站| 欧美激情精品久久久久久免费印度| 国产一区二区久久精品| 最新69国产成人精品视频免费| 久热精品视频在线| 日韩日本欧美亚洲| 欧美精品手机在线| 精品中文字幕久久久久久| 欧美亚洲第一区| 国产精品普通话| 日韩亚洲一区二区| 日韩av毛片网| 国产精品久久久久高潮| 国内精品小视频在线观看| 51ⅴ精品国产91久久久久久| 91在线视频成人| 国产精品久久久久久久久久99| 欧美午夜丰满在线18影院| 亚洲日韩欧美视频一区| 日日狠狠久久偷偷四色综合免费| 亚洲精品电影网站| 亚洲国产精品久久91精品| 国产亚洲人成a一在线v站| 欧美成aaa人片在线观看蜜臀| 久久99青青精品免费观看| 伊人久久综合97精品| 精品无人区乱码1区2区3区在线| 国产伦精品免费视频| 亚洲aaaaaa| 日韩在线中文字幕| 亚洲iv一区二区三区| 精品免费在线视频| 91免费看国产| 精品国产乱码久久久久久虫虫漫画| 欧美裸体男粗大视频在线观看| 在线视频日韩精品| 久久久999国产精品| 亚洲综合在线做性| 亚洲欧美日韩直播| 精品国产成人av| 黑人巨大精品欧美一区二区免费| 欧美成人激情视频| 91av视频导航| 国产99久久精品一区二区 夜夜躁日日躁| 国产999精品久久久| 成人在线播放av| 国产精品美女www爽爽爽视频| 精品香蕉在线观看视频一| 国产精品jvid在线观看蜜臀| 久久久久久高潮国产精品视| 亚洲国产精品va在线看黑人动漫| 91免费在线视频| 日韩精品在线免费观看视频| 日韩精品高清视频| 91在线直播亚洲| 伊人久久久久久久久久久久久| 日韩av中文在线| 国产一区二区三区丝袜| 亚洲性av网站| 日韩成人xxxx| 精品国产福利在线| 亚洲综合国产精品| 尤物精品国产第一福利三区| 欧美日韩在线影院| 欧美猛交免费看| 亚洲性av在线| 国产日韩综合一区二区性色av| 97久久伊人激情网| 欧美另类第一页| 精品在线观看国产| 国产+成+人+亚洲欧洲| 国产日韩亚洲欧美| 亚洲欧美成人一区二区在线电影| 亚洲毛茸茸少妇高潮呻吟| 久久久视频精品| 日韩中文字幕网址| 亚洲色无码播放| 久久夜色精品亚洲噜噜国产mv| 国产精品99一区| 亚洲欧美日韩网| 国产精品白丝jk喷水视频一区| 国产精品青草久久久久福利99| 国产视频久久久久久久| 欧美激情按摩在线| 欧美性xxxxx极品娇小| 日韩成人在线视频| 亚洲精品www| 中文字幕久精品免费视频| 日韩不卡在线观看| 欧美肥婆姓交大片| 性欧美xxxx交| 亚洲欧洲偷拍精品| 国产精品久久久久久久久久ktv| 在线成人激情视频| 国产乱人伦真实精品视频| 欧美疯狂xxxx大交乱88av| 久久成人综合视频| 亚洲精品国偷自产在线99热| 欧美激情精品久久久| 国产精品成熟老女人| 国产精品色视频| 国产精品欧美激情在线播放| 日韩成人xxxx| 欧洲中文字幕国产精品| 国模极品一区二区三区| 国内免费久久久久久久久久久| 日韩免费在线看| 日韩av片电影专区| 亚洲欧美综合区自拍另类| 国产精品色午夜在线观看| 国产精品亚洲欧美导航| 亚洲精品国产精品国产自| 欧美与黑人午夜性猛交久久久| 97视频在线观看播放| 国产成人精品久久亚洲高清不卡| 国产精品国产自产拍高清av水多| 欧美高清电影在线看| 欧美性猛交xxxxx免费看| 亚洲视频欧美视频| 国产一区二区三区网站| 亚洲成年网站在线观看| 欧美精品激情blacked18| 亚洲天堂免费视频| 欧美日韩成人精品| 国产亚洲精品高潮| 欧美日韩在线视频一区| 国产精品永久免费视频| 91av网站在线播放| 国产高清视频一区三区| 欧美疯狂xxxx大交乱88av| 国产日产亚洲精品| 亚洲加勒比久久88色综合| 久久久国产精品一区| 亚洲欧美另类人妖|