自動目錄
過去我們寫PHP,就知道函數名稱或是類別名稱不同重覆,如果有重覆,就不能同時include以免出現 PHP Fatal error: Cannot redeclare class xxxx in ....的錯誤。當程式規模還不大時,一切都是可以控制的,但是一旦規模長大時(共同開發或是引用他人函式庫),無可避免的同名的問題就會層出不窮,還好到了php5.3版以後,支援了命名空間,新增了use和namespace兩個操作子,有寫過其他語言的朋友也許會覺得很熟悉吧。
namespace 運算元
為避免函數或類別重覆,就可以指定命名空間namespace。
use 運算元
use 運算元其實是建立命名空間的別名,有三種用法,假設我的命名空間是:
法一: use Solar\Earth as Earth; //建立Solar\Earth的別名叫Earth
法二: use Solar\Earth; // 同上,但沒用 as,php自動會把最後一個 "\"後的字元當成是別名
法三: use yourClass; 使用全域類別,請參看狀況一修正3
請注意
-- use 和namespace這兩個操作子都必需是全域的,寫在文件的最上方,換句話說,不能寫在函式、方法或類別中。否則會出現這樣的錯誤:
Namespace declaration statement has to be the very first statement in the script in ....
-- use 可以用多個並用(聯集),畢竟他只是宣告別名,但是namespace就不能多個,如果不小心宣告多個,會以最後一個為準。
下面的範例中,同樣的函式名 showme分別在同樣的類別名稱中,利用不同的namespace來叫用:
// 檔案use.class_1.php namespace Solar\Earth; class Dynamics{ function showme(){ return __METHOD__; } } // 檔案 use.class_2.php namespace Solar\Moon; class Dynamics{ function showme(){ return __METHOD__; } }
狀況:
include "use.class_1.php"; include "use.class_2.php"; $obj = new Dynamics(); print $obj->showme();
出現錯誤 PHP Fatal error: Class 'Dynamics' not found in .... 因為同時include兩個有指定「命名空間的類別」卻沒有在new的時候指定他們。校正:
[修正1] new 的時候明確指名用哪一個命名空間
include "use.class_1.php";
include "use.class_2.php";
$obj = new Solar\Earch\Dynamics();
print $obj->showme(); // Solar\Earth\Dynamics::showme
[修正2] 使用namespace運算子
namespace Solar\Earth;
include "use.class_1.php";
include "use.class_2.php";
$obj = new Dynamics();
print $obj->showme();
[修正3] 使用use運算子
use Solar\Moon;
include "use.class_1.php";
include "use.class_2.php";
$obj = new Moon\Dynamics();
print $obj->showme();
[修正4] 使用全域的函數,如果還有一個全域類別也叫Dynamics,沒命名空間,在這種情況要叫用,就直接
namespace Dynamics;
include "use.class_1.php";
include "use.class_2.php";
$obj = new Dynamics();
print $obj->showme(); //Dynamics\Dynamics::showme
參考資料
[1] http://php.net/manual/en/language.namespaces.importing.php
[2] How to Use PHP Namespaces, Part 2: Importing, Aliases, and Name Resolution