<?php /** * Class MyArrayAccess * 提供像访问数组一样访问对象的能力的接口 */ class MyArrayAccess implements ArrayAccess { private $container; public function __construct(Array $arr) { $this->container = $arr; } // 某键是否存在 返回布尔值 public function offsetExists($offset) { var_dump(__METHOD__); return isset($this->container[$offset]); } // 获取键对应的值 返回值mixed public function offsetGet($offset) { var_dump(__METHOD__); return isset($this->container[$offset]) ? $this->container[$offset] : null; } // 赋值 public function offsetSet($offset, $value) { if (is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; } var_dump(__METHOD__); } // 删除键值 public function offsetUnset($offset) { unset($this->container[$offset]); var_dump(__METHOD__); } }
运行:
string(27) "MyArrayAccess::offsetExists" bool(true) string(24) "MyArrayAccess::offsetGet" int(2) string(26) "MyArrayAccess::offsetUnset" string(27) "MyArrayAccess::offsetExists" bool(false) string(24) "MyArrayAccess::offsetSet" string(24) "MyArrayAccess::offsetGet" string(7) "A value" string(24) "MyArrayAccess::offsetGet" A valuestring(24) "MyArrayAccess::offsetSet" string(24) "MyArrayAccess::offsetSet" string(24) "MyArrayAccess::offsetSet" object(MyArrayAccess)#1 (1) { ["container":"MyArrayAccess":private]=> array(6) { ["one"]=> int(1) ["three"]=> int(3) ["two"]=> string(7) "A value" [0]=> string(8) "Append 1" [1]=> string(8) "Append 2" [2]=> string(8) "Append 3" } }
<?php /** * 单例
* 四私一公 */ trait Singleton { static private $instance; private function __construct() { } private function __clone() { } private function __wakeup() { } static public function getInstance() { if (is_null(static::$instance)) { $class = new ReflectionClass(get_called_class()); static::$instance = $class->newInstanceWithoutConstructor(); $method = $class->getConstructor(); $method->setAccessible(true); $method->invokeArgs(static::$instance, func_get_args()); } return static::$instance; } } /** * 对象当数组用 */ class myAccess implements ArrayAccess { use Singleton; private $dataSource = []; /** * 可返回任意类型 */ public function offsetGet($offset) { var_dump(__METHOD__); return $this->dataSource[$offset] ?? null; } /** * 无返回值 */ public function offsetSet($offset, $value) { var_dump(__METHOD__); $this->dataSource[$offset] = $value; } /** * 返回布尔值 * 如果用empty()检测且返回值为true,则自动调用offsetGet */ public function offsetExists($offset) { var_dump(__METHOD__); return isset($this->dataSource[$offset]); } /** * 无返回值 */ public function offsetUnset($offset) { var_dump(__METHOD__); unset($this->dataSource[$offset]); } } // use echo '<pre>'; $obj = myAccess::getInstance(); $obj['name'] = 'tom'; isset($obj['name']); empty($obj['name']); unset($obj['name']); var_dump($obj);