资讯专栏INFORMATION COLUMN

【PHP高级特性】ArrayAccess 接口

mrli2016 / 450人阅读

摘要:提供了个常用的预定义接口,实现某些特定的能力。是啥如官方文档所述,它提供像访问数组一样访问对象的能力的接口。它提供了个接口我们实现这个接口,依次对应数组的读取,设置,操作。用上了它,可以让一个类即可以支持对象引用,也支持数组引用。

php提供了6个常用的预定义接口,实现某些特定的能力。其中最最常用的就是 ArrayAccess 了,像 Laravel 这种流行的框架都用到了它。

ArrayAccess 是啥

如官方文档所述,它“提供像访问数组一样访问对象的能力的接口”。

它提供了4个接口

/**
 * 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 

* An offset to check for. *

* @return boolean true on success or false on failure. *

*

* 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

* The offset to retrieve. *

* @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

* The offset to assign the value to. *

* @param mixed $value

* The value to set. *

* @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

* The offset to unset. *

* @return void * @since 5.0.0 */ public function offsetUnset($offset); }

我们实现这4个接口,依次对应数组的isset,读取,设置,unset操作。

有什么用

定义说的很明白啦,提供像访问数组一样访问对象的能力。用上了它,可以让一个类即可以支持对象引用,也支持数组引用。

代码实现示例

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"]);

参考

预定义接口

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29691.html

相关文章

  • PHP SPL 笔记

    摘要:界面包含四个必须部署的方法下面就是一个部署界面的实例使用方法如下运行结果如下可以看到,虽然是一个,但是完全可以像那样操作。示例如下类也支持类方法和方法类和类类和类,只支持遍历一维数组。 这几天,我在学习PHP语言中的SPL。 这个东西应该属于PHP中的高级内容,看上去很复杂,但是非常有用,所以我做了长篇笔记。不然记不住,以后要用的时候,还是要从头学起。 由于这是供自己参考的笔记,不是教...

    hoohack 评论0 收藏0
  • PHP - Pimple 源码笔记(上)

    摘要:也就是闲时为了写文章而写的一篇关于源码的阅读笔记。是标准库的缩写,一组旨在解决标准问题的接口和类的集合。提供了一套标准的数据结构,一组遍历对象的迭代器,一组接口,一组标准的异常,一系列用于处理文件的类,提供了一组函数,具体可以查看文档。 也就是闲时为了写文章而写的一篇关于 Pimple 源码的阅读笔记。Pimple 代码有两种编码方式,一种是以 PHP 编写的,另一种是以 C 扩展编写...

    cfanr 评论0 收藏0
  • 【SPL标准库专题(3)】Classes

    摘要:我把分为五个部分,,,,而其中是就是做一些类的介绍与相关的类在各自文章内,在介绍这些类之前,先介绍几个接口数组式访问接口只要实现了这个接口,就可以使得像那样操作。只有内部的类用写的类才可以直接实现接口代码中使用或接口来实现遍历。 我把SPL分为五个部分:Iterator,Classes,Exceptions,Datastructures,Function;而其中classes是就是做一...

    binaryTree 评论0 收藏0
  • ArrayAccess使用详解和实现配置化程序

    摘要:简介数组式访问接口提供像访问数组一样访问对象的能力的接口。下面我带你们一起看看我是这么实现的在项目更目录下创建一个目录在目录下创建相应的配置文件,比如和。 简介 ArrayAccess(数组式访问)接口:提供像访问数组一样访问对象的能力的接口。 提供接口 ArrayAccess { //检查一个偏移位置是否存在 abstract public boolean offse...

    李涛 评论0 收藏0
  • PHP 依赖注入

    摘要:通常调用一个类里面的方法需要如何操作依赖注入模式用来减少程序间的耦合依赖注入共有三种模式方法注入着重说下方法注入并结合单例注册的服务数组访问接口测试邮件发送成功方式访问通过数组的方式访问也是通过该方式实现依赖 通常调用一个类里面的方法需要如何操作: $class = new class();$class->fun() 依赖注入模式用来减少程序间的耦合 依赖注入共有三种模式: sette...

    zengdongbao 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<