目錄php
命名空間是相似於文件系統的一個虛擬容器,能夠用於類(包括抽象類和traits)、接口、函數、常量。bash
相似於文件系統,能夠把類放進一個多層級的命名空間,主要是解決類名的命名衝突問題。app
<?php
namespace haha\hehe\heihei
const CON1 = 10;
function run(){
//....
}
class ClassA{
//....
}
- 用namespace聲明一個命名空間,代表接下去的代碼屬於這個命名空間
- 聲明語句必須是文件第一句
- 也能夠在後面加個大括號來顯式代表這個命名空間範圍,這樣能夠作到一個文件中有多個命名空間,可是很是不建議這樣,不必,沒有可讀性,通常就是這樣使用,也不用大括號
複製代碼
沒有命名空間以前,就是ide
require('\src\ClassA.php');
new ClassA();
複製代碼
有了命名空間後函數
//如今都配合自動加載,不require
new \haha\hehe\heihei\ClassA();
複製代碼
若是屢次要new一個對象,以爲累贅,能夠這樣ui
use haha\hehe\heihei\ClassA; //注意最前面的斜槓能夠省略
$obj1 = new ClassA();
$obj2 = new ClassA();
$obj3 = new ClassA();
複製代碼
這叫導入類,還能夠給類起別名spa
use haha\hehe\heihei\ClassA as A; //注意最前面的斜槓能夠省略
new A();
複製代碼
<?php
namespace My\n1amespace
new \app\controller\User(); //徹底限定名 很清楚
new User(); //就解析爲My\n1amespace\User
new haha\User(); //就解析爲My\n1amespace\haha\User
複製代碼
__NAMESPACE__常量code
<?php
namespace My\n1amespace{
echo 'inside'.__NAMESPACE__; //My\n1amespace 若是沒有命名空間就是''
}
複製代碼
若是你須要用一個類,那你得先require,當你用一個類的時候,可能無所謂,當你的類用的多的時候,就很麻煩了。對象
自動加載1.0,在命名空間出現以前,就有自動加載,與原理就是,你能夠告訴php解釋器一個函數(用__autoload()或者spl_autoload_register()註冊
),當你用一個類,而又沒有導入的時候,系統就會運行這個函數。接口
自動加載2.0,在命名空間出現後,PSR-4規定了一個基於命名空間的統一的自動加載規範
其實問題的核心是,如何從命名空間,獲得實際的文件位置?
兩點
看一個例子就知道
spl_autoload_register(function($class_name){
//命名空間前綴
$prefixe = '\Foo\\Bar';
//基目錄
$base_dir = __DIR__.'/src/';
//匹配是否 是在尋找這個命名空間下的類
$len = strlen($prefix);
if(strncmp($prefix,$class_name,$len)!==0){
return ;
}
//將命名空間轉換爲目錄位置
$relative_class = substr($class.$len);
$file = $base_dir . str_replace('\\','/',$relative_class).'.php';
if(file)existst($file)){
require($file);
}
})
複製代碼
參考資料