遵循PSR-4的自動加載


一、簡介

  首先這里要了解PSR,Proposing a Standards Recommendation(提出標准建議)的縮寫,就是一種PHP開發規范,讓我們研發出來的代碼更合理、更好維護、可讀性更高。PSR有下面幾個標准:

  •   PSR-0:自動加載
  •   PSR-1:基本代碼規范
  •     PSR-2:代碼樣式
  •   PSR-3:日志接口
  •   PSR-4:規范自動加載的路徑問題

  這里看出PSR的下標也是從0開始的,和數組還有點像~。其實PSR-4和PSR-0是有點相似甚至冗余的,他們都說明的是自動加載的規范,只不過PSR-4中的規范更加簡潔,在PSR-0中下划線"_"是有特殊含義的,在autoload處理的時候需要將下划線轉換為目錄分隔符,而在PSR-4中下划線是沒有任何特殊含義的,所以在文件自動加載的時候顯得更加簡潔、調理更加清楚。

  我對github上面的psr-4規范中的例子進行了大概的翻譯(相信你們的英語水平一定比我好,肯定可以看懂^_^),然后以這個自動加載類庫做了一個小小的例子,例子文件多、長,放在這里不太合適,所以我在博客中就大概介紹下這個例子,想要詳細了解的可以去我的github主頁去看這個例子。

二、 自動加載類庫介紹

  首先看下自動加載類的大概內容:

class Autoload

  {
    // 注冊自動加載函數到spl autoload棧中.
     public function register();

    // 添加一個目錄到一個命名空間前綴中
    public function addNamespace($prefix, $base_dir, $prepend=false);

    // 自動加載函數,會在$this->register中用到
    public function loadClass($class);

    // 尋找映射的文件
    public function loadMappedFile($prefix, $relative_class);

    //查看一個文件是否在文件系統中存在
    public function requireFile($file);

  }

  自動加載類庫函數中就這幾個函數,其中register()、addNamespace()、loadMappedFile()、requireFile()函數都比較簡單,一看就懂,唯一一個可能需要解釋下的函數就是loadClass函數,先看下loadClass()函數的代碼:

 1     public function loadClass($class)
 2     {
 3         // 當前的命名空間前綴
 4         $prefix = $class;
 5         
 6         //通過命名空間去查找對應的文件
 7         while (false !== $pos = strrpos($prefix, '\\')) {
 8             
 9             // 可能存在的命名空間前綴
10             $prefix = substr($class, 0, $pos + 1);
11 
12             // 剩余部分是可能存在的類
13             $relative_class = substr($class, $pos + 1);
14 
15             //試圖加載prefix前綴和relitive class對應的文件
16             $mapped_file = $this->loadMappedFile($prefix, $relative_class);
17             if ($mapped_file) {
18                 return $mapped_file;
19             }
20 
21             // 移動命名空間和relative class分割位置到下一個位置
22             $prefix = rtrim($prefix, '\\');   
23         }
24         
25         // 未找到試圖加載的文件
26         return false;
27     }

  其實有疑惑的地方可能也只有一個,那就是為什么這里要循環着去試圖查找文件,在while循環中,會慢慢的縮短命名空間前綴的名稱去需找合適的命名空間前綴,為什么要這么做呢?

  循環查找文件是為了在命名空間中包含更多的內容,不用每次在父命名空間中新建一個文件夾的時候都去添加一個新的命名空間前綴,就像下面這個圖中描述的那樣:

  當一個文件在一個命名空間下的子目錄下的時候,我們不用去新建命名空間前綴就可以成功加載需要的文件,維護命名空間前綴的數組內容更少,更好維護。相反的如果沒有循環查找,就是下面這個樣子的

  

  每次新建一個子目錄就要去新加一個命名空間前綴,是不是很麻煩,但這樣的話也有一定的好處,就是加載的時候不暈循環查找文件,可能會減小一定的時間消耗,但就是加載的時候有點麻煩。

  所以,用循環加載這種方式還是比較方便的,但是一定不能讓沒有命名空間前綴的目錄層級太深,這樣會消耗不必要的時間到文件加載上。當需要效率很高的時候,而我們的目錄肯定又不會不確定,這個時候加載的時候去掉循環查找,而是為每個目錄添加命名空間,效率可能會提高,只是我的一點愚見。

三、 例子

  說道這里你可能已經對自動加載的內容比較了解了,這個時候趁熱打鐵看看我准備的小例子,這里只是介紹下小例子的目錄結構,由於比較簡單,詳細的內容就不再這里列了,感興趣的通許可以去我的github主頁看看這個例子

+autoload
+core
|_Autoload.php
+vendor
+test1
|_hello.php
+test2
|_world.php
|_App.php

  本文版權歸作者(luluyrt@163.com)和博客園共有,未經作者本人同意禁止任何形式的轉載,轉載文章之后必須在文章頁面明顯位置給出作者和原文連接,否則保留追究法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM