PHP 定義済みインターフェイス ArrayAccess、php スケジュール済み arrayaccess_PHP チュートリアル
PHP预定义接口之 ArrayAccess,php预定arrayaccess
最近这段时间回家过年了,博客也没有更新,感觉少学习了好多东西,也错失了好多的学习机会,就像大家在春节抢红包时常说的一句话:一不留神错过了好几亿。废话少说,这篇博客给大家说说关于PHP预定义接口中常用到的重量级人物: ArrayAccess。大家也许会问,最基本、最常用的预定义接口有6个呢,为啥非得说这个。从日常的使用情况来看:这个出现的频率非常高,特别是在框架中,比如Laravel、Slim等都会用到,并且用得非常经典,让人佩服啊。从技术上说:说实话其他的我用的少啊!只是知道简单的用法,对他的理解比较浅显,不敢在这里误导大家,哈哈!今天我要写的内容也不一定都正确,不对之处还请指正。
ArrayAccess
先说 ArrayAccess 吧!ArrayAccess 的作用是使得你的对象可以像数组一样可以被访问。应该说 ArrayAccess 在PHP5中才开始有的,PHP5中加入了很多新的特性,当然也使类的重载也加强了,PHP5 中添加了一系列接口,这些接口和实现的 Class 统称为 SPL。
ArrayAccess 这个接口定义了4个必须要实现的方法:
<span>1</span> <span>{ </span><span>2</span> <span>abstract</span> <span>public</span> offsetExists (<span>$offset</span>) <span>//</span><span>检查偏移位置是否存在</span> <span>3</span> <span>abstract</span> <span>public</span> offsetGet (<span>$offset</span>) <span>//</span><span>获取一个偏移位置的值</span> <span>4</span> <span>abstract</span> <span>public</span> void offsetSet (<span>$offset</span> ,<span>$value</span>) <span>//</span><span>设置一个偏移位置的值</span> <span>5</span> <span>abstract</span> <span>public</span> void offsetUnset (<span>$offset</span>) <span>//</span><span>复位一个偏移位置的值</span> <span>6</span> }
所以我们要使用ArrayAccess这个接口,就要实现相应的方法,这几个方法不是随便写的,我们可以看一下 ArrayAccess 的原型:
<span> 1</span> <span>/*</span><span>* </span><span> 2</span> <span> * Interface to provide accessing objects as arrays. </span><span> 3</span> <span> * @link http://php.net/manual/en/class.arrayaccess.php </span><span> 4</span> <span>*/</span> <span> 5</span> <span>interface</span><span> ArrayAccess { </span><span> 6</span> <span> 7</span> <span>/*</span><span>* </span><span> 8</span> <span> * (PHP 5 >= 5.0.0)<br/> </span><span> 9</span> <span> * Whether a offset exists </span><span>10</span> <span> * @link http://php.net/manual/en/arrayaccess.offsetexists.php </span><span>11</span> <span> * @param mixed $offset <p> </span><span>12</span> <span> * An offset to check for. </span><span>13</span> <span> * </p> </span><span>14</span> <span> * @return boolean true on success or false on failure. </span><span>15</span> <span> * </p> </span><span>16</span> <span> * <p> </span><span>17</span> <span> * The return value will be casted to boolean if non-boolean was returned. </span><span>18</span> <span>*/</span> <span>19</span> <span>public</span> <span>function</span> offsetExists(<span>$offset</span><span>); </span><span>20</span> <span>21</span> <span>/*</span><span>* </span><span>22</span> <span> * (PHP 5 >= 5.0.0)<br/> </span><span>23</span> <span> * Offset to retrieve </span><span>24</span> <span> * @link http://php.net/manual/en/arrayaccess.offsetget.php </span><span>25</span> <span> * @param mixed $offset <p> </span><span>26</span> <span> * The offset to retrieve. </span><span>27</span> <span> * </p> </span><span>28</span> <span> * @return mixed Can return all value types. </span><span>29</span> <span>*/</span> <span>30</span> <span>public</span> <span>function</span> offsetGet(<span>$offset</span><span>); </span><span>31</span> <span>32</span> <span>/*</span><span>* </span><span>33</span> <span> * (PHP 5 >= 5.0.0)<br/> </span><span>34</span> <span> * Offset to set </span><span>35</span> <span> * @link http://php.net/manual/en/arrayaccess.offsetset.php </span><span>36</span> <span> * @param mixed $offset <p> </span><span>37</span> <span> * The offset to assign the value to. </span><span>38</span> <span> * </p> </span><span>39</span> <span> * @param mixed $value <p> </span><span>40</span> <span> * The value to set. </span><span>41</span> <span> * </p> </span><span>42</span> <span> * @return void </span><span>43</span> <span>*/</span> <span>44</span> <span>public</span> <span>function</span> offsetSet(<span>$offset</span>, <span>$value</span><span>); </span><span>45</span> <span>46</span> <span>/*</span><span>* </span><span>47</span> <span> * (PHP 5 >= 5.0.0)<br/> </span><span>48</span> <span> * Offset to unset </span><span>49</span> <span> * @link http://php.net/manual/en/arrayaccess.offsetunset.php </span><span>50</span> <span> * @param mixed $offset <p> </span><span>51</span> <span> * The offset to unset. </span><span>52</span> <span> * </p> </span><span>53</span> <span> * @return void </span><span>54</span> <span>*/</span> <span>55</span> <span>public</span> <span>function</span> offsetUnset(<span>$offset</span><span>); </span><span>56</span> }
下面我们可以写一个例子,非常简单:
<span> 1</span> <?<span>php </span><span> 2</span> <span>class</span> Test <span>implements</span><span> ArrayAccess </span><span> 3</span> <span>{ </span><span> 4</span> <span>private</span> <span>$testData</span><span>; </span><span> 5</span> <span> 6</span> <span>public</span> <span>function</span> offsetExists(<span>$key</span><span>) </span><span> 7</span> <span> { </span><span> 8</span> <span>return</span> <span>isset</span>(<span>$this</span>->testData[<span>$key</span><span>]); </span><span> 9</span> <span> } </span><span>10</span> <span>11</span> <span>public</span> <span>function</span> offsetSet(<span>$key</span>, <span>$value</span><span>) </span><span>12</span> <span> { </span><span>13</span> <span>$this</span>->testData[<span>$key</span>] = <span>$value</span><span>; </span><span>14</span> <span> } </span><span>15</span> <span>16</span> <span>public</span> <span>function</span> offsetGet(<span>$key</span><span>) </span><span>17</span> <span> { </span><span>18</span> <span>return</span> <span>$this</span>->testData[<span>$key</span><span>]; </span><span>19</span> <span> } </span><span>20</span> <span>21</span> <span>public</span> <span>function</span> offsetUnset(<span>$key</span><span>) </span><span>22</span> <span> { </span><span>23</span> <span>unset</span>(<span>$this</span>->testData[<span>$key</span><span>]); </span><span>24</span> <span> } </span><span>25</span> <span>} </span><span>26</span> <span>27</span> <span>$obj</span> = <span>new</span><span> Test(); </span><span>28</span> <span>29</span> <span>//</span><span>自动调用offsetSet方法</span> <span>30 </span> <span>$obj</span>['data'] = 'data'<span>; </span><span>31</span> <span>32</span> <span>//</span><span>自动调用offsetExists</span> <span>33 </span> <span>if</span>(<span>isset</span>(<span>$obj</span>['data'<span>])){ </span><span>34</span> <span>echo</span> 'has setting!'<span>; </span><span>35</span> <span>} </span><span>36</span> <span>//</span><span>自动调用offsetGet</span> <span>37</span> <span>var_dump</span>(<span>$obj</span>['data'<span>]); </span><span>38</span> <span>39</span> <span>//</span><span>自动调用offsetUnset</span> <span>40</span> <span>unset</span>(<span>$obj</span>['data'<span>]); </span><span>41</span> <span>var_dump</span>(<span>$test</span>['data'<span>]); </span><span>42</span> <span>43</span> <span>//</span><span>输出: </span><span>44</span> <span>//has setting! </span><span>45</span> <span>//data </span><span>46</span> <span>//null</span>
好了,下面我们会结合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等等,使他们在框架加载的时候首先被加载。使用的时候直接取就可以了,
下面就是这种加载机制:
<?<span>php namespace Slim; </span><span>use</span><span> Interop\Container\ContainerInterface; </span><span>use</span> Interop\Container\<span>Exception</span><span>\ContainerException; </span><span>use</span> Pimple\Container <span>as</span><span> PimpleContainer; </span><span>use</span><span> Psr\Http\Message\ResponseInterface; </span><span>use</span><span> Psr\Http\Message\ServerRequestInterface; </span><span>use</span> Slim\<span>Exception</span><span>\ContainerValueNotFoundException; </span><span>class</span> Container <span>extends</span> PimpleContainer <span>implements</span><span> ContainerInterface { </span><span>/*</span><span>* * Default settings * * @var array </span><span>*/</span> <span>private</span> <span>$defaultSettings</span> =<span> [ </span>'httpVersion' => '1.1', 'responseChunkSize' => 4096, 'outputBuffering' => 'append', 'determineRouteBeforeAppMiddleware' => <span>false</span>, 'displayErrorDetails' => <span>false</span>,<span> ]; </span><span>/*</span><span>* * Create new container * * @param array $values The parameters or objects. </span><span>*/</span> <span>public</span> <span>function</span> __construct(<span>array</span> <span>$values</span> =<span> []) { </span><span>//</span><span>var_dump($values); exit;</span> parent::__construct(<span>$values</span><span>); </span><span>$userSettings</span> = <span>isset</span>(<span>$values</span>['settings']) ? <span>$values</span>['settings'] :<span> []; </span><span>$this</span>->registerDefaultServices(<span>$userSettings</span><span>); } </span><span>private</span> <span>function</span> registerDefaultServices(<span>$userSettings</span><span>) { </span><span>$defaultSettings</span> = <span>$this</span>-><span>defaultSettings; </span><span>$this</span>['settings'] = <span>function</span> () <span>use</span> (<span>$userSettings</span>, <span>$defaultSettings</span><span>) { </span><span>return</span> <span>new</span> Collection(<span>array_merge</span>(<span>$defaultSettings</span>, <span>$userSettings</span><span>)); }; </span><span>$defaultProvider</span> = <span>new</span><span> DefaultServicesProvider(); </span><span>$defaultProvider</span>->register(<span>$this</span><span>); } </span>. . .<span> }</span>
其中 defaultSettings 为系统默认配置,userSettings为用户的配置,比如日志,模板等。
下面这段是offsetGet,巧妙使用键值来判断该值是否已经设置过,如果设置过就会直接去取了,没有设置就会转到设置的逻辑。
<span> 1</span> <span>public</span> <span>function</span> offsetGet(<span>$id</span><span>) </span><span> 2</span> <span> { </span><span> 3</span> <span>if</span> (!<span>isset</span>(<span>$this</span>->keys[<span>$id</span><span>])) { </span><span> 4</span> <span>throw</span> <span>new</span> \InvalidArgumentException(<span>sprintf</span>('Identifier "%s" is not defined.', <span>$id</span><span>)); </span><span> 5</span> <span> } </span><span> 6</span> <span> 7</span> <span>if</span><span> ( </span><span> 8</span> <span>isset</span>(<span>$this</span>->raw[<span>$id</span><span>]) </span><span> 9</span> || !<span>is_object</span>(<span>$this</span>->values[<span>$id</span><span>]) </span><span>10</span> || <span>isset</span>(<span>$this</span>-><span>protected</span>[<span>$this</span>->values[<span>$id</span><span>]]) </span><span>11</span> || !<span>method_exists</span>(<span>$this</span>->values[<span>$id</span>], '__invoke'<span>) </span><span>12</span> <span> ) { </span><span>13</span> <span>return</span> <span>$this</span>->values[<span>$id</span><span>]; </span><span>14</span> <span> } </span><span>15</span> <span>16</span> <span>if</span> (<span>isset</span>(<span>$this</span>->factories[<span>$this</span>->values[<span>$id</span><span>]])) { </span><span>17</span> <span>return</span> <span>$this</span>->values[<span>$id</span>](<span>$this</span><span>); </span><span>18</span> <span> } </span><span>19</span> <span>20</span> <span>$raw</span> = <span>$this</span>->values[<span>$id</span><span>]; </span><span>21</span> <span>$val</span> = <span>$this</span>->values[<span>$id</span>] = <span>$raw</span>(<span>$this</span><span>); </span><span>22</span> <span>$this</span>->raw[<span>$id</span>] = <span>$raw</span><span>; </span><span>23</span> <span>24</span> <span>$this</span>->frozen[<span>$id</span>] = <span>true</span><span>; </span><span>25</span> <span>26</span> <span>return</span> <span>$val</span><span>; </span><span>27</span> }
我们再看看 PimpleContainer,如下图:
我们可以看到其中有个 SplObjectStorage,需要说一下这个,SplObjectStorage是用来存储一组对象,当你需要唯一标识对象的时候。按照官网的说法 PHP SPL SplObjectStorage类实现了Countable, Iterator, Serializable, ArrayAccess四个接口,可实现统计、迭代、序列化、数组式访问等功能。所以SplObjectStorage是一个标准的对象容器。
说到这大家对ArrayAccess应该有所了解了,如果还不清楚,可以多看看Slim的源码,上面写的比较清楚,而且那套源码及其的简练,值得我们学习。
博客会同步更新到我的个人网站,欢迎大家访问!
转载请注明出处,后面会持续更新,谢谢大家!

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7

PHPとPythonにはそれぞれ独自の利点があり、プロジェクトの要件に従って選択します。 1.PHPは、特にWebサイトの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンス、機械学習、人工知能に適しており、簡潔な構文を備えており、初心者に適しています。

PHPは、電子商取引、コンテンツ管理システム、API開発で広く使用されています。 1)eコマース:ショッピングカート機能と支払い処理に使用。 2)コンテンツ管理システム:動的コンテンツの生成とユーザー管理に使用されます。 3)API開発:RESTFUL API開発とAPIセキュリティに使用されます。パフォーマンスの最適化とベストプラクティスを通じて、PHPアプリケーションの効率と保守性が向上します。

PHPは依然として動的であり、現代のプログラミングの分野で重要な位置を占めています。 1)PHPのシンプルさと強力なコミュニティサポートにより、Web開発で広く使用されています。 2)その柔軟性と安定性により、Webフォーム、データベース操作、ファイル処理の処理において顕著になります。 3)PHPは、初心者や経験豊富な開発者に適した、常に進化し、最適化しています。

PHPは主に手順プログラミングですが、オブジェクト指向プログラミング(OOP)もサポートしています。 Pythonは、OOP、機能、手続き上のプログラミングなど、さまざまなパラダイムをサポートしています。 PHPはWeb開発に適しており、Pythonはデータ分析や機械学習などのさまざまなアプリケーションに適しています。

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 Pythonと比較して、PHPはWeb開発においてより多くの利点がありますが、データサイエンスの分野ではPythonほど良くありません。 Javaと比較して、PHPはエンタープライズレベルのアプリケーションでより悪化しますが、Web開発により柔軟性があります。 JavaScriptと比較して、PHPはバックエンド開発により簡潔ですが、フロントエンド開発のJavaScriptほど良くありません。

PHPとPythonには独自の利点と短所があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1.PHPは、大規模なWebアプリケーションの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンスと機械学習の分野を支配しています。
