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 這個帶有命名空間的類,會有以下幾個步驟.
- 嘗試 去掉 首字母 \
- 將類中的 \ 轉換成 系統的文件夾分隔符 DIRECTORY_SEPARATOR ,此時去找的類文件會變成 Core / ClassLoader
- 查看接下來的類文件中是否存在 _ 下劃線 ,如果存在,則轉換爲 文件夾分隔符.
- 添加文件後綴名 .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 下對自動加載類的 實現。