【php】自動加載類autoload psr-0與psr-4標準

psr-0 與 psr-4 標準

最近一直想整理一下關於php的自動加載類的方式進行一個總結。每個人都想在自己的代碼中少一些include 和 require 的操作, 這樣不僅能方便代碼編寫,而且能夠減少不必要的引入類文件衝突的問題。下面我們分別來介紹 psr-0 和 psr-4 規範.

PSR-0規範
1 命名空間必須與絕對路徑一致
2 類名首字母必須大寫
3 除去入口文件外,其他“.php”必須只有一個類
4 php類文件必須自動載入,不採用include等
5 單一入口

案例
當有一個項目的路徑是如下圖所示:
這裏寫圖片描述

Request.php 的代碼是:

<?php
class Http_Request{

    // ... 這裏是類代碼
    public function __construct(){
         echo '自動加載成功';
    }
}
?>

當我們的 index.php 文件需要引入 Request.php 裏的類時 ,我們發現直接寫路徑是十分困難的事情,也許會因爲太長而不小心寫錯.因此引入了psr-0的這種自動加載規範。
index.php 代碼

<?php 

// 引入了我們做好的 自動加載類方法
require_once __DIR__ . '/lib' . '/autoload.php';
$request = new Http_Request();
?>

autoload.php 代碼

<?php
// 自動加載方法 
function auto_load_psr0($class){
    // 獲取 lib的絕對路徑
    $libDir  =  __DIR__ .DIRECTORY_SEPARATOR;

    // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
    if ('\\' == $class[0]) {
        $class = substr($class, 1);
    }

    // 獲取psr4標準的邏輯路徑
    $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . ".php";

    // PSR-0 lookup
    if (false !== $pos = strrpos($class, '\\')) {
        // 命名空間文件加載 namespaced class name
        $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
            . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
    } else {
        // PEAR-like class name
        $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . ".php";
    }

    // 如果文件存在 則引入
    if (file_exists($file = $libDir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
        includeFile( $file);
    }
    //

}

function includeFile($file)
{
    include $file;
}
// 註冊 psr-0 自動加載規範
spl_autoload_register("auto_load_psr0" , true , true);
?>

運行結果:

這裏寫圖片描述

小結:這是一個基本的使用psr-0規範進行自動加載的方式,主要是將類名中的 _ 下劃線 轉換成 文件夾分割線 / or \ ,再加上自己定義好的一個路徑或者路徑集合進行查找是否符合 自定義文件夾($dir)+”/”+” Http/Request” + 後綴(.php) 的文件,如果存在就可以進行包含了。

PSR-0 命名空間類加載例子
這裏寫圖片描述

Core\ClassLoader.php 如何自動加載

<?php
namespace Core;
class ClassLoader{
    public function __construct(){
        print_r("自動加載 classLoader");
    }
}
?>

修改 index.php

<?php
require_once __DIR__ . '/lib' . '/autoload.php';
    $classLoader = new \Core\ClassLoader();
?>

實際上 \Core\ClassLoader 這個帶有命名空間的類,會有以下幾個步驟.

  1. 嘗試 去掉 首字母 \
  2. 將類中的 \ 轉換成 系統的文件夾分隔符 DIRECTORY_SEPARATOR ,此時去找的類文件會變成 Core / ClassLoader
  3. 查看接下來的類文件中是否存在 _ 下劃線 ,如果存在,則轉換爲 文件夾分隔符.
  4. 添加文件後綴名 .php

最後 需要include 的文件變成 包含文件目錄下 + Core/ClassLoader.php

PSR-4規範
PSR-4和PSR-0最大的區別是對下劃線(underscore)的定義不同。PSR-4中,在類名中使用下劃線沒有任何特殊含義。而PSR-0則規定類名中的下劃線_會被轉化成目錄分隔符。
PSR-4會預先加載目錄映射,如上面的例子爲例,\Core\ClassLoader 類在Core命名空間裏,PSR-4規範會設定一個路徑來指定Core命名空間屬於某一個文件夾(example: \Core\ => vendor/myApp/Core/src/ ) 這樣去找類的時候, 就會去對應的目錄下去找。

注意: PSR-4 規範 要求在設置命名空間映射是,要求命名空間尾部含有 \符號。以表示爲命名空間類。

更多關於PSR-0 和 PSR-4的規範,其實可以去閱讀composer 下對自動加載類的 實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章