php提供了6個經常使用的預約義接口,實現某些特定的能力。其中最最經常使用的就是 ArrayAccess 了,像 Laravel 這種流行的框架都用到了它。php
ArrayAccess 是啥數組
如官方文檔所述,它「提供像訪問數組同樣訪問對象的能力的接口」。框架
它提供了4個接口ide
/** * Interface to provide accessing objects as arrays. * @link http://php.net/manual/en/class.arrayaccess.php */ interface ArrayAccess { /** * Whether a offset exists * @link http://php.net/manual/en/arrayaccess.offsetexists.php * @param mixed $offset <p> * An offset to check for. * </p> * @return boolean true on success or false on failure. * </p> * <p> * The return value will be casted to boolean if non-boolean was returned. * @since 5.0.0 */ public function offsetExists($offset); /** * Offset to retrieve * @link http://php.net/manual/en/arrayaccess.offsetget.php * @param mixed $offset <p> * The offset to retrieve. * </p> * @return mixed Can return all value types. * @since 5.0.0 */ public function offsetGet($offset); /** * Offset to set * @link http://php.net/manual/en/arrayaccess.offsetset.php * @param mixed $offset <p> * The offset to assign the value to. * </p> * @param mixed $value <p> * The value to set. * </p> * @return void * @since 5.0.0 */ public function offsetSet($offset, $value); /** * Offset to unset * @link http://php.net/manual/en/arrayaccess.offsetunset.php * @param mixed $offset <p> * The offset to unset. * </p> * @return void * @since 5.0.0 */ public function offsetUnset($offset); }
咱們實現這4個接口,依次對應數組的isset,讀取,設置,unset操做。this
有什麼用.net
定義說的很明白啦,提供像訪問數組同樣訪問對象的能力。用上了它,可讓一個類便可以支持對象引用,也支持數組引用。code
代碼實現示例對象
class Container implements ArrayAccess { /** * @var array 單例對象索引 */ private $instances = []; /** * @var array 可實例化對象定義索引 */ private $definitions = []; public function offsetExists($offset) { return isset($this->definitions[$offset]); } public function offsetGet($offset) { if (isset($this->instances[$offset])) { return $this->instances[$offset]; } elseif (isset($this->definitions[$offset])) { return $this->make($offset); } throw new \Exception('未提供對象定義'); } public function offsetSet($offset, $value) { // ... 省略一些較驗判斷 $this->definitions[$offset] = $value; } public function offsetUnset($offset) { unset($this->definitions[$offset]); unset($this->instances[$offset]); } private function make($offset) { $definition = $this->definitions[$offset]; if ($definition instanceof \Closure) { return $this->instances[$offset] = $definition(); } if (is_object($definition)) { return $this->instances[$offset] = $definition; } if (is_array($definition)) { $class = $definition['class']; $reflection = new \ReflectionClass($class); $dependencies = []; // ... 省略反射的實現代碼 $object = $reflection->newInstanceArgs($dependencies); return $this->instances[$offset] = $object; } throw new \Exception('對象定義不合法'); } }
使用示例索引
$container = new Container(); $container['test'] = function () { return 'this is a test'; }; var_dump(isset($container['test'])); echo $container['test']; unset($container['test']);
參考接口