PHP命令空間namespace及use的用法(執行個體)

來源:互聯網
上載者:User
這篇文章主要介紹了PHP命令空間namespace及use的用法實踐總結,需要的朋友可以參考下

命名空間一個最明確的目的就是解決重名問題,PHP中不允許兩個函數或者類出現相同的名字,否則會產生一個致命的錯誤。這種情況下只要避免命名重複就可以解決,最常見的一種做法是約定一個首碼。

使用namespace的目的:

團隊合作項目時,避免與團隊其它成員建立的類發生衝突;個人負責項目時,避免前後建立的類發生衝突;

據個人理解,用到所需要的類時,需要先require或include引入,所以會發生類重定義的錯誤的前提是:兩個相同命名的類都有被引入。目前有些php架構會自動載入(即include)所有建立的model類,所以為了避免你建立的model類和項目架構原生的核心類發生重名衝突,採用了namespace。(想了想,與團隊成員建立的類產生衝突應該通過溝通避免,即使事發後也應該重新調整類名即時維護,避免後期造成因為對類的理解混淆而帶來維護上的複雜度提高)

結合使用方法來進一步理解它的使用目的吧。

namespace的使用方法:

為了進行測試,我將建立3個檔案:1.php和name.php(此檔案用來執行測試),後面將不再說明,請自行注意代碼的變化。

1.namespace後命名的定義不區分大小寫

namespace one;
namespace One;
namespace ONE;

如上寫法都可以,選擇一種作為自己的規範即可。(後面代碼我採用第一種進行測試哈)

2. 沒有定義命名空間,就理解為使用頂級命名空間。new類時,可以在類前加上反斜線\,也可以不加。

//1.php class Person{ function __construct(){  echo 'I am one!'; }}//name.phprequire_once './1.php';new Person(); //輸出 I am one!;new \Person(); //輸出 I am one!;

3. new類時,帶上命名空間時,之間一定用反斜線字元,而不是順斜杠。

記憶方法:按找%中斜杠的順序理解為順斜杠。(有時說反斜線,自己都不知道是哪種方向,以前按自左向右上升方向這種方向記憶,現在感覺這個太不靠譜了)

//name.phprequire_once './1.php';new /Person(); // 代碼報錯:Parse error: syntax error, unexpected '/'

4.類在指定命名空間下, new類時,一定要帶上指定的命名空間。

沒有帶上指定的命名空間,按照第2點,php就會從頂級命名空間裡找這個類。切記:這裡不能按照頂級命名空間包含一切其它的命名空間來理解。而應該將頂級命名空間完完全全與其他命名空間區分開。

//1.php namespace one;class Person{ function __construct(){  echo 'I am one!'; }}//name.phprequire_once './1.php';new \one\Person(); //輸出 I am one!;new \Person(); //代碼報錯:Fatal error: Class 'Person' not found

可以舉個這個通俗例子來理解:帶上指定命名空間代表某人的蘋果(在他手裡),頂級命名空間代表蘋果箱裡的蘋果(在箱子裡)。現在要找某人的蘋果,就將某人的命名空間帶上,否則就會從箱子裡找某人的蘋果,結果當然是找不到。

5.命名空間聲明後的代碼便屬於這個命名空間,即使有include或require也不影響(重點是對後半句的理解,具體看代碼)。

//1.php namespace one;class Person{ function __construct(){  echo 'I am one!'; }}//name.phpnamespace test;require './1.php'; new \one\Person(); //輸出 I am one!;new Person(); //這裡結果會是什麼呢,猜猜看

最後一行結果報錯:

Fatal error: Class 'test\Person' not found

首先,這裡與第2點比較一下:

第2點,我說,沒有命名空間時,new類時,有沒有反斜線意義一樣。

在這裡,有了命名空間,有和沒有反斜線的意義就不一樣了。

最後一行換成

new \Person();

結果報錯:

Fatal error: Class 'Person' not found

接著,就說說當前這點。

我們可以發現,最後一行代碼對應的命名空間為test,並沒有受到require檔案裡的命名空間的影響。

進一步加強驗證,我修改了name.php檔案如下:

//name.phpnamespace test;require './1.php'; class Person{ function __construct(){  echo 'I am test!'; }}new \one\Person(); //輸出 I am one!;new Person(); //這裡結果會是什麼,自己猜猜看

最後,這個例子重新整理了我對require的認識了。

按照我以前對require的理解:PHP 程式在執行前,就會先讀入 require 所指定引入的檔案,使它變成 PHP 程式網頁的一部分。所以我常常就簡單的理解為替換,只不過把抽離出來的代碼再放回原處而已。然後我試了將1.php檔案內容放到name.php裡:

//name.phpnamespace test;namespace one;class Person{ function __construct(){  echo 'I am one!'; }}class Person{ function __construct(){  echo 'I am test!'; }}

無需new類,該檔案就會報錯:

Fatal error: Cannot redeclare class one\Person

看來簡單的把require理解為替換,在這裡行不通。

6.namespace裡不包含類名稱,即使存在與類名稱同名的部分,那也不代表類。new類時,還是得將這部分帶上。

//name.phpnamespace test\person;class Person{ function __construct(){  echo 'I am test!'; }}new \test\person\Person();  //命名空間裡person無法代表類名

不過這樣純粹是畫蛇添足,直接乾脆點,namespace裡不要帶類名稱就好。

7.一個php檔案中可以存在多個命名空間,第一個命名空間前不能有任何代碼。

只說第一個命名空間前不能有任何代碼,之後的命名空間之前可以有代碼。這個自行測試即可。

//name.phpnamespace test;echo 'zhai14';namespace zhai;require './1.php';

php命名空間namespace告一段落了,接下來說說use的用途。

使用use的目的:

在命名空間字串過長時,使用use可以相應的縮短命名空間。

use的使用方法:

1.new類時,最前面無需用反斜線。此外,use後沒有as時,縮短的命名空間預設為最後一個反斜線後的內容。

//name.phpnamespace animal\dog;class Life{ function __construct(){  echo 'dog life!'; }}namespace animal\cat;class Life{ function __construct(){  echo 'cat life!'; }}new Life(); //按照代碼執行順序,這裡預設animal\cat這個命名空間new \animal\dog\Life(); //Ause animal\dog; //anew dog\Life(); //Buse animal\dog as d; //bnew d\Life();

通過A、B行代碼比較,需要注意:

使用use後,new類時,最前面沒有反斜線。

沒使用use時,命名空間最前面有反斜線

通過a、b行代碼比較,可以理解:

use後沒有as時,縮短的命名空間預設為最後一個反斜線後的內容。如上的:

use animal\dog;

相當於

use animal\dog as dog;

2.namespace後面不建議加類名,但use後可以。

//name.phpnamespace animal\dog;class Life{ function __construct(){  echo 'dog life!'; }}namespace animal\cat;class Life{ function __construct(){  echo 'cat life!'; }}use animal\dog\Life as dog; new dog();

如上所示,use後加上類名後,就相當於把類改了個名稱:由Life改為dog了。

上面不用as dog就會報錯:

Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
因為cat下也有個一樣名稱的Life類。

可以理解為,使用use後,這個暱稱對應的類只能歸當前命名空間佔有,其它命名空間下不允許存在該類。

//name.phpnamespace animal\dog;class Life{ function __construct(){  echo 'dog life!'; }}class Dog{ function __construct(){  echo 'dog in dog!'; }}namespace animal\cat;// class Dog{// function __construct(){//  echo 'dog in cat!';//  }// }class Life{ function __construct(){  echo 'cat life!'; }}use animal\dog; new dog\Dog();

如上,使用了

use animal\dog;
cat

通過上面代碼,我想使用use的目的效果(縮短命名空間名稱)就很明顯了。

簡單總結一下:

namespace就是劃分領域的作用,代表這些東西是屬於某個命名空間下的。

use就是起小名的作用,不論寫起來還是說起來都可以省不少事兒。

相關推薦:

PHP命令空間的用法大全

php user_error()函數的簡介

有關php user_error()函數的文章推薦10篇

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.