PHPPHP预定义接口的 ArrayAccess

  最近及时段时回家过年了,博客也尚无更新,感觉少上了成千上万事物,也丧失了很多之学会,就如大家在新春佳节赶紧红包时常说之同一句子话:一不留神错过了好几亿。废话少说,这首博客给大家说说关于PHP预定义接口中常因此到的重量级人士: ArrayAccess。大家莫不会咨询,最基本、最常用的预定义接口有6个也,为啥不得说这个。从日常的动状态来拘禁:这个起的频率十分高,特别是在框架中,比如Laravel、Slim等还见面因此到,并且因此得够呛经典,让人钦佩啊。从技术上说:说实话其他的本身为此底散失啊!只是了解简单的用法,对客的知情比较浅,不敢在此间误导大家,哈哈!今天己要是描绘的内容也非肯定都没错,不对准的处还请求指正。

ArrayAccess

  先说 ArrayAccess 吧!ArrayAccess
的用意是驱动你的靶子可以像数组一样可以让看。应该说 ArrayAccess
在PHP5中才起有的,PHP5中投入了诸多初的表征,当然为使类的重载也增强了,PHP5
中上加了同等多样接口,这些接口及促成之 Class 统称为 SPL。

ArrayAccess 这个接口定义了4只必使兑现之章程:

1 {
2    abstract public offsetExists ($offset)  //检查偏移位置是否存在
3    abstract public offsetGet ($offset)     //获取一个偏移位置的值
4    abstract public void offsetSet ($offset ,$value) //设置一个偏移位置的值
5    abstract public void offsetUnset ($offset)       //复位一个偏移位置的值
6 }

为此我们只要使用ArrayAccess这个接口,就要实现相应的计,这几独道不是随便写的,我们得看一下
ArrayAccess 的原型:

 1 /**
 2  * Interface to provide accessing objects as arrays.
 3  * @link http://php.net/manual/en/class.arrayaccess.php
 4  */
 5 interface ArrayAccess {
 6 
 7     /**
 8      * (PHP 5 &gt;= 5.0.0)<br/>
 9      * Whether a offset exists
10      * @link http://php.net/manual/en/arrayaccess.offsetexists.php
11      * @param mixed $offset <p>
12      * An offset to check for.
13      * </p>
14      * @return boolean true on success or false on failure.
15      * </p>
16      * <p>
17      * The return value will be casted to boolean if non-boolean was returned.
18      */
19     public function offsetExists($offset);
20 
21     /**
22      * (PHP 5 &gt;= 5.0.0)<br/>
23      * Offset to retrieve
24      * @link http://php.net/manual/en/arrayaccess.offsetget.php
25      * @param mixed $offset <p>
26      * The offset to retrieve.
27      * </p>
28      * @return mixed Can return all value types.
29      */
30     public function offsetGet($offset);
31 
32     /**
33      * (PHP 5 &gt;= 5.0.0)<br/>
34      * Offset to set
35      * @link http://php.net/manual/en/arrayaccess.offsetset.php
36      * @param mixed $offset <p>
37      * The offset to assign the value to.
38      * </p>
39      * @param mixed $value <p>
40      * The value to set.
41      * </p>
42      * @return void
43      */
44     public function offsetSet($offset, $value);
45 
46     /**
47      * (PHP 5 &gt;= 5.0.0)<br/>
48      * Offset to unset
49      * @link http://php.net/manual/en/arrayaccess.offsetunset.php
50      * @param mixed $offset <p>
51      * The offset to unset.
52      * </p>
53      * @return void
54      */
55     public function offsetUnset($offset);
56 }

 下面我们可以描绘一个例证,非常简单:

 1 <?php
 2 class Test implements ArrayAccess
 3 {
 4     private $testData;
 5 
 6     public function offsetExists($key)
 7     {
 8         return isset($this->testData[$key]);
 9     }
10 
11     public function offsetSet($key, $value)
12     {
13         $this->testData[$key] = $value;
14     }
15 
16     public function offsetGet($key)
17     {
18         return $this->testData[$key];
19     }
20 
21     public function offsetUnset($key)
22     {
23         unset($this->testData[$key]);
24     }
25 }
26 
27   $obj = new Test();
28 
29   //自动调用offsetSet方法
30   $obj['data'] = 'data';
31 
32   //自动调用offsetExists
33   if(isset($obj['data'])){
34     echo 'has setting!';
35   }
36   //自动调用offsetGet
37   var_dump($obj['data']);
38 
39   //自动调用offsetUnset
40   unset($obj['data']);
41   var_dump($test['data']);
42 
43   //输出:
44   //has setting!
45   //data  
46   //null

  好了,下面我们见面成Slim框架来说在事实上中之下,在Slim中动用特别主要,也殊美妙的使用了
container,container继承自Pimple\Container,说到即,就闹必不可少说一下Pimple,pimple是php社区被比流行的等同种植ioc容器,pimple中之container类使用了指注入的办法来贯彻实现了程序中的亚耦合,可以据此composer添加
require  “pimple/pimple”: “1.*” 添加Pimple到依赖类库,Pimple还是如多看的,就一个文书,在先后整个生命周期中,各种性能、方法、对象、闭包都得注册中,但pimple只是实现了一个容器的概念,还有许多依靠注入、自动创建、关联等功能要看Laravel才能够深切学到。

  在Slim中它采取 container
的近乎实现了以布文件相继加载,可以像看数组一样看他们,包括displayErrorDetails,renderer,
logger,httpVersion,responseChunkSize,outputBuffering,determineRouteBeforeAppMiddleware,displayErrorDetails等等,使她们在框架加载的时刻首先被加载。使用的早晚一直沾就可了,

下就是这种加载机制:

<?php

namespace Slim;

use Interop\Container\ContainerInterface;
use Interop\Container\Exception\ContainerException;
use Pimple\Container as PimpleContainer;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Exception\ContainerValueNotFoundException;

class Container extends PimpleContainer implements ContainerInterface
{
    /**
     * Default settings
     *
     * @var array
     */
    private $defaultSettings = [
        'httpVersion' => '1.1',
        'responseChunkSize' => 4096,
        'outputBuffering' => 'append',
        'determineRouteBeforeAppMiddleware' => false,
        'displayErrorDetails' => false,
    ];

    /**
     * Create new container
     *
     * @param array $values The parameters or objects.
     */
    public function __construct(array $values = [])
    {
        //var_dump($values);          exit;
        parent::__construct($values);

        $userSettings = isset($values['settings']) ? $values['settings'] : [];
        $this->registerDefaultServices($userSettings);
    }

    private function registerDefaultServices($userSettings)
    {
        $defaultSettings = $this->defaultSettings;

        $this['settings'] = function () use ($userSettings, $defaultSettings) {
            return new Collection(array_merge($defaultSettings, $userSettings));
        };

        $defaultProvider = new DefaultServicesProvider();
        $defaultProvider->register($this);
    }

    . . .

}

中 defaultSettings
为系统默认配置,userSettings为用户的部署,比如日志,模板等。

下就段是offsetGet,巧妙运用键值来判断该值是否早已安装了,如果设置过就是会一直去获取了,没有安装就会见变动至安装的逻辑。

 1     public function offsetGet($id)
 2     {
 3         if (!isset($this->keys[$id])) {
 4             throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
 5         }
 6 
 7         if (
 8             isset($this->raw[$id])
 9             || !is_object($this->values[$id])
10             || isset($this->protected[$this->values[$id]])
11             || !method_exists($this->values[$id], '__invoke')
12         ) {
13             return $this->values[$id];
14         }
15 
16         if (isset($this->factories[$this->values[$id]])) {
17             return $this->values[$id]($this);
18         }
19 
20         $raw = $this->values[$id];
21         $val = $this->values[$id] = $raw($this);
22         $this->raw[$id] = $raw;
23 
24         $this->frozen[$id] = true;
25 
26         return $val;
27     }

俺们重看看 PimpleContainer,如下图:

PHP 1

     我们得以视里边有只
SplObjectStorage,需要说一下夫,SplObjectStorage是为此来储存一组对象,当您需要唯一标识对象的时。按照官网的布道
PHP SPL SplObjectStorage类实现了Countable, Iterator, Serializable,
ArrayAccess四单接口,可实现统计、迭代、序列化、数组式访问等功能。所以SplObjectStorage是一个规范的对象容器。

  说到即大家对ArrayAccess应该有了解了,如果还无亮堂,可以多省Slim的源码,上面写的比较清楚,而且那套源码及其的简短,值得我们念。

      博客会同步创新至自我的私有网站,欢迎大家看!

注意:

1、本博客同步创新到自家的民用网站:http://www.zhaoyafei.cn

2、本文属原创内容,为了强调别人劳动,转载请注明本文地址:

http://www.cnblogs.com/zyf-zhaoyafei/p/5228652.html

 

相关文章