PHP物件導向 – 命名空間

來源:互聯網
上載者:User

標籤:空間   hello   設計   not found   dex   csdn   分隔字元   總結   程式設計   

PHP自5.3.0開始,引入了一個namespace關鍵字以及__NAMESPACE__魔術常量(當然use關鍵字或use as嵌套語句也同時引入);那麼什麼是命名空間呢?php官網已很明確的進行了定義並形象化解釋,這裡直接從php官網copy一段文字[來源]。

“什麼是命名空間?從廣義上來說,命名空間是一種封裝事物的方法。在很多地方都可以見到這種抽象概念。例如,在作業系統中目錄用來將相關檔案分組,對於目錄中的檔案來說,它就扮演了命名空間的角色。具體舉個例子,檔案 foo.txt 可以同時在目錄/home/greg 和 /home/other 中存在,但在同一個目錄中不能存在兩個 foo.txt 檔案。另外,在目錄 /home/greg 外訪問 foo.txt 檔案時,我們必須將目錄名以及目錄分隔字元放在檔案名稱之前得到 /home/greg/foo.txt。這個原理應用到程式設計領域就是命名空間的概念。”

目前php5.5系列早已推出,php的物件導向編程思想也在逐漸的完善,而本文要學習的namespace關鍵字的引入就是為瞭解決php物件導向編程過程中已出現的各種“麻煩”;具體麻煩如下:

1、使用者編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字衝突。

2、為了緩解麻煩1,通常編寫各種class時會使用較長的類名或為實現不同功能的class添加名稱首碼(或尾碼)。

3、不使用魔法函數__autoload的情況下,而每個class又獨佔一個php檔案時,為了調用不同的class,會在使用這些class的另外的php檔案的開頭位置書寫較多的include(或require或require_once)語句。

============

命名空間的使用概要:

tips:以下樣本中成為了兩個檔案,一個Demo.php,一個index.php,兩個檔案處於同級目錄下;Demo.php檔案中書寫命名空間以及Demo類,index.php調用Demo.php中的Demo類;如下樣本中的“輸出結果”即表示瀏覽器訪問index.php。

一、簡單的樣本

Demo.php檔案代碼

<?php
namespace DemoNameSpace;

class Demo {
private $mysqlHandle;

public function __construct() {
echo ‘This is namespace of PHP demo ,The Demo magic constant "__NAMESPACE__" is ‘.__NAMESPACE__;
}
}
?>

index.php檔案代碼

<?php
include ‘Demo.php‘;
use DemoNameSpace\Demo;
$DemoObj = new Demo();
?>

輸出結果1:“This is namespace of PHP demo ,The Demo magic constant "__NAMESPACE__" is DemoNameSpace”

以上樣本的說明:Demo.php中有一個_NAMESPACE__魔法常量;“它包含當前命名空間名稱的字串。在全域的,不包括在任何命名空間中的代碼,它包含一個空的字串。”

接著做樣本:

Demo.php不做變動,改動index.php檔案,如下:

<?php
include ‘Demo.php‘;
$Demo = new Demo();
?>

輸出結果2:“Fatal error: Class ‘Demo‘ not found in F:\JJserver\demo\index.php on line 4”

這個是常見的“致命錯誤”資訊了。按照常規的php編程思路,這裡的輸出應該是跟“輸出結果1”一致的,但這裡它偏要來個致命錯誤,這下要抓狂了吧?~

行,先把抓狂的麻煩解決,去掉(或注釋掉)Demo.php檔案中的:“namespace DemoNameSpace;”這個語句,就正常了。這是咱們平常寫class以及調用class最常見的書寫方法,就不再解釋這種不使用namespace的情況了。

對比使用namespace與不使用namespace的兩種輸出情況,並加入namespace的定義理解後,上述出現致命錯誤的情況就很好理解了。在Demo.php中定義了一個namespace,也就是命名空間後,接著定義了Demo類,然後這個Demo類就被歸併到了DemoNameSpace命名空間中去了,那麼要調用這個Demo類時,自然要先調用這個DemoNameSpace命名空間了,也就是在index.php檔案中使用“use DemoNameSpace\Demo”語句了。

二、複雜一點的樣本

Demo.php檔案代碼

<?php
namespace DemoNameSpace;

class Demo {
private $mysqlHandle;

public function __construct() {
echo ‘This is namespace of PHP demo ,The Demo magic constant "__NAMESPACE__" is ‘.__NAMESPACE__;
}
}

namespace DemoNameSpace1;
const constDefine = ‘JJonline1‘;
class Demo {
private $mysql;
const constDefine = ‘JJonline2‘;

public function __construct() {
echo ‘The const constant outside class is: ‘.constDefine;
echo ‘===cut-off rule of god!!!!===‘;
echo ‘The const constant inside class is: ‘.self::constDefine;
}
}
?>
index.php檔案代碼
<?php
include ‘Demo.php‘;
use DemoNameSpace1\Demo as Test;
$Demo = new Test();
echo ‘||||‘.DemoNameSpace1\constDefine;
?>

輸出結果3:“The const constant outside class is: JJonline1===cut-off rule of god!!!!===The const constant inside class is: JJonline2||||JJonline1”

這個結果在沒有命名空間的時候,就直接報諸如“Fatal error: Cannot redeclare class Demo”的致命錯誤了。但運行沒有報錯,這也就是php5.3以後引入的命名空間的好處了,就諸如本文開頭引用的官方解釋中以不同目錄下的相同檔案名稱的檔案可以存在一樣是一個道理了。Demo.php檔案中,定義的第一個名稱叫做Demo的class類被歸併到了DemoNameSpace的命名空間,而定義的第二個名稱叫做Demo的class被歸併到了DemoNameSpace1的命名空間,故而並不會出現不能重複定義某一個類的致命錯誤。以上的書寫方法是要盡量避免的,因為類外部const常量名與類內部const常量名是一樣的,很容易混淆,這裡這樣書寫的目的就是看看不同位置申明的const常量,在調用時的情況;輸出結果3已經很明顯了,就不再多墨跡解釋了。

Demo.php中DemoNameSpace1命名空間下還將const常量constDefine提出,拿到了定義class之外,這又要抓狂了,因為之前的知識是define定義全域常量,const定義class內部常量;這兒卻將const拿出來玩了...具體就不再講解了,Demo.php檔案代碼以及運行後的結果已經很明確的表明了相關知識。class內部定義的const只能在class的內部調用,採用self::constName形式,而class內部調用命名空間下、class外的const常量,則可以直接使用諸如define定義的常量一樣使用。當需要使用該命名空間下、class外定義的const常量時,就使用類似路徑形式的方式調用(index.php檔案中的輸出)。

該例子還有一點說明,就是在index.php中使用了use as語句,看index.php的代碼,意義一目瞭然,new的一個class名稱叫Test,但Test這個類並沒有在Demo.php中定義,卻沒有出錯,這就在於了use as語句了,具體意義不再解釋。

通過上述的瞭解,namespace關鍵字可以將實現各種功能的class通過指定不同的命名空間分門別類存放,而且不同命名空間下的class可以同名;另外const常量定義也可以提出到class外部,當然也會有作用範圍這麼一個“內涵”~

總結下namespace的相關知識:

1、當前指令檔的第一個命名空間前面不能有任何代碼,例如如下代碼就是會報致命錯誤的:

<?php
define("GREETING","Hello world!");

namespace DemoNameSpace;

class Demo {
private $mysqlHandle;

public function __construct() {
echo ‘This is namespace of PHP demo ,The Demo magic constant "__NAMESPACE__" is ‘.__NAMESPACE__;
}
}
$Demo = new Demo();
?>

運行上述代碼,會出現致命錯誤:“Fatal error: Namespace declaration statement has to be the very first statement in xxxx”

2、命名空間下直接new該命名空間中的class名稱,可以省略掉use文法,這是php按指令碼書寫順序執行導致的。例如如下代碼是可以啟動並執行

<?php
namespace DemoTest;
class Demo {
public function __construct() {
echo ‘this is a test script‘;
}
}
namespace DemoNameSpace;

class Demo {
private $mysqlHandle;

public function __construct() {
echo ‘This is namespace of PHP demo ,The Demo magic constant "__NAMESPACE__" is ‘.__NAMESPACE__;
}
}
$Demo = new Demo();
?>

運行結果4:“This is namespace of PHP demo ,The Demo magic constant "__NAMESPACE__" is DemoNameSpace”

這個結果表明,同一指令碼下new一個沒有指定use哪個命名空間時,會順著該指令碼,使用最靠近new語句之前的一個命名空間中的class

3、公用空間:可以簡單的理解,沒有定義命名空間的方法(函數)、類庫(class)、屬性(變數)都預設歸屬於公用空間。這樣就解釋了為php5.3.0以前版本書寫的代碼大部分為何在php5.3.0及其以上版本還能正常啟動並執行原因。另外:公用空間中的程式碼片段被引入到某個命名空間下後,該公用空間中的程式碼片段不屬於任何命名空間!

公用空間這塊,還是各位自己寫寫代碼比較好。

4、就如目錄結構一樣,命名空間也有子命名空間的概念,具體就不再舉例說明了。

命名空間的引入,讓php物件導向編程更加的貼切,合理利用命名空間,也可以讓專案檔規劃,各個類庫規劃更加的合理、易讀。更多關於php5.3.0及其以上引入的命名空間的問題就不再介紹了。

PHP物件導向 – 命名空間

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.