如何理解PHP核心特性命名空間
提出
PHP 在 5.3 后提出了命名空間用來(lái)解決組件之間的命名沖突問(wèn)題,主要參考了文件系統(tǒng)的設(shè)計(jì):
- 同一個(gè)目錄下不允許有相同的文件名 - 同一個(gè)命名空間下不允許有相同的類(lèi);
- 不同的目錄可以有同名文件 - 不同的命名空間可以有相同的類(lèi);
定義
使用namespace關(guān)鍵字來(lái)定義一個(gè)命名空間。其中,頂層命名空間通常為廠(chǎng)商名,不同開(kāi)發(fā)者的廠(chǎng)商命名空間是唯一的。命名空間不需要與文件目錄一一對(duì)應(yīng),但是最好遵守PSR-4規(guī)范。
<?php
namespace Symfony\Component\HttpFoundation;
class Request {
}
命名空間必須在所有代碼之前聲明,唯一的例外就是 declare 關(guān)鍵字。
<?php
declare(strict_types=1);
namespace App;
命名空間內(nèi)可包含任意 PHP 代碼,但是僅對(duì)類(lèi) (包括抽象類(lèi)和 Trait)、接口、函數(shù)和常量這四種類(lèi)型生效。
<?php
namespace MyProject;
const CONNECT_OK = 1;
class FOO {}
interface Foo{}
function foo() {}
使用
使用use關(guān)鍵字來(lái)引入命名空間
<?php
namespace App;
use Symfony\Component\HttpFoundation\Request;
use Foo\Bar;
class Test {
public function run()
{
$bar = new Bar();
}
}
定義和使用推薦遵循PSR-2的規(guī)范
- namespace之后必須存在一個(gè)空行;
- 所有use聲明必須位于namespace聲明之后;
- 每條use聲明必須只有一個(gè)use關(guān)鍵字。
use語(yǔ)句塊之后必須存在一個(gè)空行。
當(dāng)use引入的類(lèi)出現(xiàn)同名時(shí),可使用as來(lái)定義別名
<?php
namespace App;
use Foo\Bar as BaseBar;
class Bar extends BaseBar {
}
限定符
除了使用use外,還可以直接使用\限定符來(lái)進(jìn)行解析,規(guī)則很簡(jiǎn)單:如果含有\(zhòng)前綴則代表從全局命名空間開(kāi)始解析,否則則代表從當(dāng)前命名空間開(kāi)始解析。
<?php
namespace App;
\Foo\Bar\foo(); // 解析成 \Foo\Bar\foo();
Foo\Bar\foo(); // 解析成 App\Foo\Bar\foo();
此規(guī)則也適用于函數(shù)、常量等
$a = \strlen('hi'); // 調(diào)用全局函數(shù) strlen
$b = \INI_ALL; // 訪(fǎng)問(wèn)全局常量 INI_ALL
$c = new \Exception('error'); // 實(shí)例化全局類(lèi) Exception
有兩個(gè)需要特別注意的地方:
對(duì)于函數(shù)和常量而言,如果當(dāng)前命名空間不存在,則會(huì)自動(dòng)去全局命名空間去尋找,因此可省略\前綴。對(duì)于類(lèi)而言,如果當(dāng)前命名空間解析不到,不會(huì)去全局空間尋找,因此,不可省略\
$a = strlen('hi');
$b = INI_ALL;
$c = new Exception('error'); // 錯(cuò)誤
$c = new \Exception('error'); // 正確
當(dāng)動(dòng)態(tài)調(diào)用命名空間時(shí),該命名空間始終會(huì)被當(dāng)成是全局命名空間,因此可以省略前綴\
$class1 = 'Foo\Bar'; $object1 = new $class1; // 始終被解析成 \Foo\Bar
在內(nèi)部訪(fǎng)問(wèn)命名空間
PHP 支持兩種抽象的訪(fǎng)問(wèn)當(dāng)前命名空間內(nèi)部元素的方法,__NAMESPACE__魔術(shù)常量和namespace關(guān)鍵字。
__NAMESPACE__常量的值是包含當(dāng)前命名空間名稱(chēng)的字符串,如果是在全局命名空間,則返回空字符串。
<?php
namespace MyProject;
function get($classname)
{
$a = __NAMESPACE__ . '\\' . $classname;
return new $a;
}
關(guān)鍵字namespace可用來(lái)顯式訪(fǎng)問(wèn)當(dāng)前命名空間或子命名空間中的元素。它等價(jià)于類(lèi)中的self操作符
namespace App; use blah\blah as mine; blah\mine(); // App\blah\mine() namespace\blah\mine(); // App\blah\mine() namespace\func(); // App\func() namespace\sub\func(); // App\sub\func() namespace\cname::method(); // App\cname::method() $a = new namespace\sub\cname(); // App\sub\cname $b = namespace\CONSTANT; // App\CONSTANT
轉(zhuǎn)義\符號(hào)
此外,推薦對(duì)所有的\進(jìn)行轉(zhuǎn)義,避免出現(xiàn)不可預(yù)期的后果
$class = "dangerous\name"; // \n 被解析成換行符 $obj = new $class; $class = 'dangerous\name'; // 正確,但是不推薦 $class = 'dangerous\\name'; // 推薦 $class = "dangerous\\name"; // 推薦
以上就是如何理解PHP核心特性命名空間的詳細(xì)內(nèi)容,更多關(guān)于PHP命名空間的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
過(guò)濾掉PHP數(shù)組中的重復(fù)值的實(shí)現(xiàn)代碼
去除一個(gè)數(shù)組中的重復(fù)值,可以使用foreach方法,也可以使用array_unique方法,下面的代碼兩種方法都使用了。2011-07-07
應(yīng)用開(kāi)發(fā)中涉及到的css和php筆記分享
最近一周使用SAE開(kāi)發(fā)一個(gè)簡(jiǎn)單的微博應(yīng)用。應(yīng)用本身很簡(jiǎn)單,使用php算法可以輕松實(shí)現(xiàn)。但是在調(diào)用新浪API的時(shí)候遇到很多各種各樣的麻煩。應(yīng)用到現(xiàn)在還有些不穩(wěn)定。2011-08-08
PHP使用PhpSpreadsheet操作Excel實(shí)例詳解
這篇文章主要介紹了PHP使用PhpSpreadsheet操作Excel,結(jié)合實(shí)例形式詳細(xì)分析了PHP使用PhpSpreadsheet操作Excel的相關(guān)組件下載、函數(shù)功能與操作技巧,需要的朋友可以參考下2020-03-03
用php實(shí)現(xiàn)批量查詢(xún)清除一句話(huà)后門(mén)的代碼
一句話(huà)后門(mén)一般簡(jiǎn)單,容易隱藏危害大,查找麻煩等。今天發(fā)現(xiàn)了這個(gè)Xall.php專(zhuān)門(mén)批量查詢(xún)干掉一句話(huà)后門(mén)的代碼,大家可以省去不少麻煩了2008-01-01
php中實(shí)現(xiàn)記住密碼自動(dòng)登錄的代碼
記得登錄QQ的時(shí)候,我們可以選記住密碼自動(dòng)登錄,這個(gè)功能確實(shí)很方便、實(shí)用。其實(shí)在我們登錄網(wǎng)站后臺(tái)的時(shí)候,瀏覽器就會(huì)有提示是否記住登錄狀態(tài)。2011-03-03

