命名空間主要為了解決用戶編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字沖突。不過並不是你定義了使用命名空間的類,就可以在任何地方隨意使用了,需要在程序運行時將定義命名空間的類文件加載(include or require)進來。但是如果將所有的命名空間都提前加載進來,顯示是不合理的。為此,php有專門的自動加載機制spl_autoload_register。下面我們通過代碼來具體看一下:
1.編寫a.php文件
1 namespace namespace_test\module; 2 3 class a 4 { 5 function __construct() 6 { 7 echo '------實例化a------<br>'; 8 } 9 10 function out() 11 { 12 echo 'hello!'; 13 } 14 }
2.編寫b.php文件
1 define('ROOT_PATH', dirname(dirname(__FILE__))); 2 3 function auto_load($class) 4 { 5 echo 'auto_load-->class: '.$class.'<br>'; 6 $arr = explode('\\', $class); 7 8 if (count($arr) > 0) 9 { 10 $file = ROOT_PATH."/{$arr[1]}_{$arr[2]}/{$arr[2]}.php"; 11 12 @include_once $file; 13 } 14 } 15 16 spl_autoload_register("auto_load"); 17 18 echo '------實例化a之前------<br>'; 19 $obj = new \namespace_test\module\a(); 20 echo '------實例化a之后------<br>'; 21 22 $obj->out();
文件目錄結構如下圖:
通過瀏覽器訪問b.php文件,程序運行結果如下:
程序說明:
spl_autoload_register("auto_load")作用是在發現未定義的類時運行auto_load()方法,auto_load的參數$class即為類的完整名稱,如上圖auto_load-->class所示。程序整個過程如下:
1.當運行到$obj = new \namespace_test\module\a(),發現未定義a;
2.調用auto_load($class)方法,a的完整類名作為參數$class傳遞給auto_load;
3.通過開發人員的自定義規則解析文件路徑,加載a.php文件;
4.實例化a,運行后續程序。
最后,說明一下關於命名空間完整類名的定義應盡量遵循PSR-4標准。
參考:
http://www.cnblogs.com/woider/p/6443854.html
https://laravel-china.org/topics/2081/psr-specification-psr-4-automatic-loading-specification
https://www.php-fig.org/psr/psr-4/