本文實(shí)例講述了PHP命名空間(namespace)原理與用法。分享給大家供大家參考,具體如下:
PHP 命名空間(namespace)是在PHP 5.3中加入的,它可以解決以下兩類(lèi)問(wèn)題:
- 用戶編寫(xiě)的代碼與PHP內(nèi)部的類(lèi)/函數(shù)/常量或第三方類(lèi)/函數(shù)/常量之間的名字沖突。
- 為很長(zhǎng)的標(biāo)識(shí)符名稱(通常是為了緩解第一類(lèi)問(wèn)題而定義的)創(chuàng)建一個(gè)別名(或簡(jiǎn)短)的名稱,提高源代碼的可讀性。
我們?cè)谀J(rèn)情況下,所有常量、類(lèi)和函數(shù)名都放在全局空間下,就和PHP支持命名空間之前一樣,命名空間通過(guò)關(guān)鍵字namespace 來(lái)聲明,如果一個(gè)文件中包含命名空間,它必須在其它所有代碼之前聲明命名空間。我們來(lái)看下語(yǔ)法:
?php
// 定義代碼在 'MyProject' 命名空間中
namespace MyProject;
// ... 代碼 ...
我們也可以在同一個(gè)文件中定義不同的命名空間代碼,如下:
?php
namespace MyProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
namespace AnotherProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
?>
不過(guò)我不建議使用這種語(yǔ)法在單個(gè)文件中定義多個(gè)命名空間,有需要的話,可以使用大括號(hào)形式的語(yǔ)法,如下:
?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace AnotherProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
?>
我們?nèi)绻獙⑷值姆敲臻g中的代碼與命名空間中的代碼組合在一起,只能使用大括號(hào)形式的語(yǔ)法,并且全局代碼必須用一個(gè)不帶名稱的 namespace 語(yǔ)句加上大括號(hào)括起來(lái),如下:
?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // 全局代碼
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
我們?cè)诼暶髅臻g之前唯一合法的代碼是用于定義源文件編碼方式的 declare 語(yǔ)句,要記住,除了這個(gè)之外的所有非 PHP 代碼包括空白符都不能出現(xiàn)在命名空間的聲明之前,如下:
?php
declare(encoding='UTF-8'); //定義多個(gè)命名空間和不包含在命名空間中的代碼
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // 全局代碼
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
看個(gè)錯(cuò)誤的寫(xiě)法:
html>
?php
namespace MyProject; // 命名空間前出現(xiàn)了“html>” 會(huì)致命錯(cuò)誤 - 命名空間必須是程序腳本的第一條語(yǔ)句
?>
與目錄和文件的關(guān)系很像,PHP 命名空間也允許指定層次化的命名空間的名稱,因此,命名空間的名字可以使用分層次的方式定義,模式如下:
?php
namespace MyProject\Sub\Level; //聲明分層次的單個(gè)命名空間
const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */ }
?>
上述代碼中,創(chuàng)建了常量 MyProject\Sub\Level\CONNECT_OK,類(lèi) MyProject\Sub\Level\Connection 和函數(shù) MyProject\Sub\Level\Connect。
咱們?cè)賮?lái)看下PHP 命名空間中的類(lèi)名的引用方式:
- 非限定名稱,或不包含前綴的類(lèi)名稱,例如 $a=new foo(); 或 foo::staticmethod();。如果當(dāng)前命名空間是 currentnamespace,foo 將被解析為 currentnamespace\foo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,則 foo 會(huì)被解析為foo。 警告:如果命名空間中的函數(shù)或常量未定義,則該非限定的函數(shù)名稱或常量名稱會(huì)被解析為全局函數(shù)名稱或常量名稱。
- 限定名稱,或包含前綴的名稱,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果當(dāng)前的命名空間是 currentnamespace,則 foo 會(huì)被解析為 currentnamespace\subnamespace\foo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,foo 會(huì)被解析為subnamespace\foo。
- 完全限定名稱,或包含了全局前綴操作符的名稱,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在這種情況下,foo 總是被解析為代碼中的文字名(literal name)currentnamespace\foo。
咱們用來(lái)個(gè)文件來(lái)演示下,首先來(lái)看f1.php的代碼:
?php
namespace Foo\Bar\subnamespace;
const FOO = 1;
function foo() {}
class foo
{
static function staticmethod() {}
}
?>
之后就是f2.php的代碼:
?php
namespace Foo\Bar;
include 'f1.php';
const FOO = 2;
function foo() {}
class foo
{
static function staticmethod() {}
}
/* 非限定名稱 */
foo(); // 解析為函數(shù) Foo\Bar\foo
foo::staticmethod(); // 解析為類(lèi) Foo\Bar\foo ,方法為 staticmethod
echo FOO; // 解析為常量 Foo\Bar\FOO
/* 限定名稱 */
subnamespace\foo(); // 解析為函數(shù) Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析為類(lèi) Foo\Bar\subnamespace\foo,
// 以及類(lèi)的方法 staticmethod
echo subnamespace\FOO; // 解析為常量 Foo\Bar\subnamespace\FOO
/* 完全限定名稱 */
\Foo\Bar\foo(); // 解析為函數(shù) Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析為類(lèi) Foo\Bar\foo, 以及類(lèi)的方法 staticmethod
echo \Foo\Bar\FOO; // 解析為常量 Foo\Bar\FOO
?>
我們?cè)L問(wèn)任意全局類(lèi)、函數(shù)或常量,都可以使用完全限定名稱,例如 \strlen() 或 \Exception 或 \INI_ALL。之后,咱們?cè)賮?lái)看下在命名空間內(nèi)部訪問(wèn)全局類(lèi)、函數(shù)和常量的實(shí)例:
?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hi'); // 調(diào)用全局函數(shù)strlen
$b = \INI_ALL; // 訪問(wèn)全局常量 INI_ALL
$c = new \Exception('error'); // 實(shí)例化全局類(lèi) Exception
?>
PHP 命名空間的實(shí)現(xiàn)受到其語(yǔ)言自身的動(dòng)態(tài)特征的影響,我們先來(lái)看一段代碼:
?php
class classname
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function funcname()
{
echo __FUNCTION__,"\n";
}
const constname = "global";
$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "\n"; // prints global
?>
我們?nèi)绻獙⑸鲜龅拇a轉(zhuǎn)換到命名空間中,并且動(dòng)態(tài)訪問(wèn)元素,就必須使用完全限定名稱(包括命名空間前綴的類(lèi)名稱)。注意因?yàn)樵趧?dòng)態(tài)的類(lèi)名稱、函數(shù)名稱或常量名稱中,限定名稱和完全限定名稱沒(méi)有區(qū)別,因此其前導(dǎo)的反斜杠是不必要的。如下:
?php
namespace namespacename;
class classname
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function funcname()
{
echo __FUNCTION__,"\n";
}
const constname = "namespaced";
include 'example1.php';
$a = 'classname';
$obj = new $a; // 輸出 classname::__construct
$b = 'funcname';
$b(); // 輸出函數(shù)名
echo constant('constname'), "\n"; // 輸出 global
/* 如果使用雙引號(hào),使用方法為 "\\namespacename\\classname"*/
$a = '\namespacename\classname';
$obj = new $a; // 輸出 namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // 輸出 namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // 輸出 namespacename\funcname
$b = '\namespacename\funcname';
$b(); // 輸出 namespacename\funcname
echo constant('\namespacename\constname'), "\n"; // 輸出 namespaced
echo constant('namespacename\constname'), "\n"; // 輸出 namespaced
?>
好啦,本次記錄就到這里了,后續(xù)的記錄會(huì)在之后的文章中有體現(xiàn)。
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語(yǔ)法入門(mén)教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
您可能感興趣的文章:- 詳細(xì)分析PHP 命名空間(namespace)
- PHP類(lèi)的自動(dòng)加載與命名空間用法實(shí)例分析
- PHP 命名空間和自動(dòng)加載原理與用法實(shí)例分析
- PHP 命名空間原理與用法詳解
- php 命名空間(namespace)原理與用法實(shí)例小結(jié)
- PHP命名空間用法實(shí)例分析
- PHP命名空間與自動(dòng)加載機(jī)制的基礎(chǔ)介紹
- php的命名空間與自動(dòng)加載實(shí)現(xiàn)方法
- 詳解PHP中的命名空間