1.命名空間
PHP 命名空間可以解決以下兩類問題:
1) 用戶編寫的代碼與PHP內(nèi)部的類/函數(shù)/常量或第三方類/函數(shù)/常量之間的名字沖突峦萎。
2) 為很長的標識符名稱(通常是為了緩解第一類問題而定義的)創(chuàng)建一個別名(或簡短)的名稱攒射,提高源代碼的可讀性朗和。
2.類自動加載
spl_autoload_register ([ callable
$autoload_function
[, bool$throw
= true [, bool$prepend
= false ]]] ) : bool
autoload_function:
欲注冊的自動裝載函數(shù)。如果沒有提供任何參數(shù)料滥,則自動注冊 autoload 的默認實現(xiàn)函數(shù)spl_autoload()。
throw:
此參數(shù)設置了autoload_function
無法成功注冊時, spl_autoload_register()是否拋出異常躺涝。
prepend:
如果是 true,spl_autoload_register() 會添加函數(shù)到隊列之首扼雏,而不是隊列尾部坚嗜。
3.psr4
1.此處的“類”泛指所有的class類夯膀、接口、traits可復用代碼塊以及其它類似結構苍蔬。
2.一個完整的類名需具有以下結構:
???? <命名空間>(<子命名空間>)*<類名>
????1)完整的類名必須要有一個頂級命名空間诱建,被稱為 "vendor namespace";
???? 2)完整的類名可以有一個或多個子命名空間碟绑;
????3)完整的類名必須有一個最終的類名俺猿;
????4)完整的類名中任意一部分中的下滑線都是沒有特殊含義的;
????5)完整的類名可以由任意大小寫字母組成格仲;
????6)所有類名都必須是大小寫敏感的押袍。
3.當根據(jù)完整的類名載入相應的文件……
????1)完整的類名中,去掉最前面的命名空間分隔符凯肋,前面連續(xù)的一個或多個命名空間和子命名空間谊惭,作為“命名空間前綴”,其必須與至少一個“文件基目錄”相對應否过;
????2)緊接命名空間前綴后的子命名空間必須與相應的”文件基目錄“相匹配午笛,其中的命名空間分隔符將作為目錄分隔符。
????3)末尾的類名必須與對應的以 .php 為后綴的文件同名苗桂。
????4)自動加載器(autoloader)的實現(xiàn)一定不能拋出異常药磺、一定不能觸發(fā)任一級別的錯誤信息以及不應該有返回值
使用PSR4,有2個好處:1. 減少代碼目錄的深度;2. 可以通過前綴快速找到映射目錄煤伟,提高自動加載的效率
ps:psr0與psr4主要區(qū)別:1.psr0比4多了 一條類名的_下劃線轉換成目錄癌佩。2.psr4比0多了一個 命名空間前綴和目錄的替換關系 當加載類的時候類名空間指定的前綴會被替換成路徑再加上后面的子空間和類名 構成實際加載地址。而0沒有這個對應關系便锨。命名空間直接轉換為目錄再加上指定的目錄前綴構成實際的加載地址围辙。
4.yii2
index.php
require($_SERVER['ENV_FRAMEWORK_DIR'] . 'autoload.php');//yii2的自動加載文件
require($_SERVER['ENV_FRAMEWORK_DIR'] . 'yiisoft/yii2/Yii.php');
require(__DIR__ . '/../common/config/bootstrap.php');
$config = require(__DIR__ . '/../ordinary/config/main.php');
autoload.php
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInitcf708c3c6363e39b2b6c83d3e69ad060::getLoader();
autoload_real.php
spl_autoload_register(array('ComposerAutoloaderInitcf708c3c6363e39b2b6c83d3e69ad060', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitcf708c3c6363e39b2b6c83d3e69ad060', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
ClassLoader.php
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
if (0 === strpos($class, $prefix)) {
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
yii2 通過require加載自身的autoload.php文件,導入autoload_real.php放案,這個文件將文件autoload_classmap.php,autoload_files,autoload_namespaces.php,autoload_psr4.php注入到類Classloader中姚建,ClassLoader通過psr-4,namaspace,files(直接require),classmap(類名=>文件所在路徑)四種方式來加載文件,順序依次是判斷classmap中有沒有這個類吱殉,有直接require他的文件路徑掸冤,然后根據(jù)psr4規(guī)則拼接路徑尋找文件,最后根據(jù)psr0規(guī)則拼接路徑尋找文件友雳,