首先这里要了解PSR,Proposing a Standards Recommendation(提出标准建议)的缩写,就是一种PHP开发规范,让我们研发出来的代码更合理、更好维护、可读性更高。PSR有下面几个标准:
这里看出PSR的下标也是从0开始的,和数组还有点像~。其实PSR-4和PSR-0是有点相似甚至冗余的,他们都说明的是自动加载的规范,只不过PSR-4中的规范更加简洁,在PSR-0中下划线"_"是有特殊含义的,在autoload处理的时候需要将下划线转换为目录分隔符,而在PSR-4中下划线是没有任何特殊含义的,所以在文件自动加载的时候显得更加简洁、调理更加清楚。
我对github上面的psr-4规范中的例子进行了大概的翻译(相信你们的英语水平一定比我好,肯定可以看懂^_^),然后以这个自动加载类库做了一个小小的例子,例子文件多、长,放在这里不太合适,所以我在博客中就大概介绍下这个例子,想要详细了解的可以去我的github主页去看这个例子。
首先看下自动加载类的大概内容:
<span>class</span><span> Autoload { </span><span>//</span><span> 注册自动加载函数到spl autoload栈中.</span> <span>public</span> <span>function</span><span> register(); </span><span>//</span><span> 添加一个目录到一个命名空间前缀中</span> <span>public</span> <span>function</span> addNamespace(<span>$prefix</span>, <span>$base_dir</span>, <span>$prepend</span>=<span>false</span><span>); </span><span>//</span><span> 自动加载函数,会在$this->register中用到</span> <span>public</span> <span>function</span> loadClass(<span>$class</span><span>); </span><span>//</span><span> 寻找映射的文件</span> <span>public</span> <span>function</span> loadMappedFile(<span>$prefix</span>, <span>$relative_class</span><span>); </span><span>//</span><span>查看一个文件是否在文件系统中存在</span> <span>public</span> <span>function</span> requireFile(<span>$file</span><span>); }</span>
自动加载类库函数中就这几个函数,其中register()、addNamespace()、loadMappedFile()、requireFile()函数都比较简单,一看就懂,唯一一个可能需要解释下的函数就是loadClass函数,先看下loadClass()函数的代码:
<span> 1</span> <span>public</span> <span>function</span> loadClass(<span>$class</span><span>) </span><span> 2</span> <span> { </span><span> 3</span> <span>//</span><span> 当前的命名空间前缀</span> <span> 4</span> <span>$prefix</span> = <span>$class</span><span>; </span><span> 5</span> <span> 6</span> <span>//</span><span>通过命名空间去查找对应的文件</span> <span> 7</span> <span>while</span> (<span>false</span> !== <span>$pos</span> = <span>strrpos</span>(<span>$prefix</span>, '\\'<span>)) { </span><span> 8</span> <span> 9</span> <span>//</span><span> 可能存在的命名空间前缀</span> <span>10</span> <span>$prefix</span> = <span>substr</span>(<span>$class</span>, 0, <span>$pos</span> + 1<span>); </span><span>11</span> <span>12</span> <span>//</span><span> 剩余部分是可能存在的类</span> <span>13</span> <span>$relative_class</span> = <span>substr</span>(<span>$class</span>, <span>$pos</span> + 1<span>); </span><span>14</span> <span>15</span> <span>//</span><span>试图加载prefix前缀和relitive class对应的文件</span> <span>16</span> <span>$mapped_file</span> = <span>$this</span>->loadMappedFile(<span>$prefix</span>, <span>$relative_class</span><span>); </span><span>17</span> <span>if</span> (<span>$mapped_file</span><span>) { </span><span>18</span> <span>return</span> <span>$mapped_file</span><span>; </span><span>19</span> <span> } </span><span>20</span> <span>21</span> <span>//</span><span> 移动命名空间和relative class分割位置到下一个位置</span> <span>22</span> <span>$prefix</span> = <span>rtrim</span>(<span>$prefix</span>, '\\'<span>); </span><span>23</span> <span> } </span><span>24</span> <span>25</span> <span>//</span><span> 未找到试图加载的文件</span> <span>26</span> <span>return</span> <span>false</span><span>; </span><span>27</span> }
其实有疑惑的地方可能也只有一个,那就是为什么这里要循环着去试图查找文件,在while循环中,会慢慢的缩短命名空间前缀的名称去需找合适的命名空间前缀,为什么要这么做呢?
循环查找文件是为了在命名空间中包含更多的内容,不用每次在父命名空间中新建一个文件夹的时候都去添加一个新的命名空间前缀,就像下面这个图中描述的那样:
三、 例子
说道这里你可能已经对自动加载的内容比较了解了,这个时候趁热打铁看看我准备的小例子,这里只是介绍下小例子的目录结构,由于比较简单,详细的内容就不再这里列了,感兴趣的通许可以去我的github主页看看这个例子
--core
-Autoload.php
--vendor
--test1
-hello.php
--test2
-world.php
-App.php
本文版权归作者(luluyrt@163.com)和博客园共有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。