首頁  >  文章  >  後端開發  >  PHP命令空間的用法大全

PHP命令空間的用法大全

php中世界最好的语言
php中世界最好的语言原創
2017-12-20 14:55:592260瀏覽

我們知道,在命名空間一個最明確的目的就是解決重名問題,所以在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.php
require_once './1.php';
new Person(); //输出 I am one!;
new \Person(); //输出 I am one!;

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

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

//name.php
require_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.php
require_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.php
namespace 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.php
namespace 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.php
namespace 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.php
namespace test\person;
class Person{
 function construct(){
  echo 'I am test!';
 }

}new \test\person\Person();  //命名空間裡person無法代表類別名稱

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

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

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

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


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

使用use的目的:

在命名空间字符串过长时,使用use可以相应的缩短命名空间。

use的使用方法:

1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。

//name.php
namespace 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(); //A
use animal\dog; //a
new dog\Life(); //B
use animal\dog as d; //b
new d\Life();


 通过A、B行代码比较,需要注意:

使用use后,new类时,最前面没有反斜杠。

没使用use时,命名空间最前面有反斜杠

通过a、b行代码比较,可以理解:

use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的:

use animal\dog;

相当于

use animal\dog as dog;

2.namespace后面不建议加类名,但use后可以。

//name.php
namespace 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.php
namespace 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就是划分领域的作用,代表这些东西是属于某个命名空间下的。


相信看了这些案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

相关阅读:

php自定义函数生成笛卡尔积的方法

PHP自定义函数生成笛卡尔积

多个数组求笛卡尔积


以上是PHP命令空間的用法大全的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn