国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home 類庫下載 PHP類庫 PHP namespace (namespace)

PHP namespace (namespace)

Oct 10, 2016 am 10:32 AM

PHP 命名空間(namespace)

PHP 命名空間(namespace)是在PHP 5.3中加入的,如果你學(xué)過C#和Java,那命名空間就不算什么新事物。 不過在PHP當(dāng)中還是有著相當(dāng)重要的意義。

PHP 命名空間可以解決以下兩類問題:

用戶編寫的代碼與PHP內(nèi)部的類/函數(shù)/常量或第三方類/函數(shù)/常量之間的名字沖突。

為很長的標(biāo)識(shí)符名稱(通常是為了緩解第一類問題而定義的)創(chuàng)建一個(gè)別名(或簡短)的名稱,提高源代碼的可讀性。

定義命名空間

默認(rèn)情況下,所有常量、類和函數(shù)名都放在全局空間下,就和PHP支持命名空間之前一樣。

命名空間通過關(guān)鍵字namespace 來聲明。如果一個(gè)文件中包含命名空間,它必須在其它所有代碼之前聲明命名空間。語法格式如下;

< ?php  
// 定義代碼在 &#39;MyProject&#39; 命名空間中  namespace MyProject;  
 
// ... 代碼 ...

你也可以在同一個(gè)文件中定義不同的命名空間代碼,如:

< ?php  
namespace MyProject1;  
// MyProject1 命名空間中的PHP代碼  
 
namespace MyProject2;  
// MyProject2 命名空間中的PHP代碼    
 
// 另一種語法
namespace MyProject3 {  
 // MyProject3 命名空間中的PHP代碼    
}  
?>

在聲明命名空間之前唯一合法的代碼是用于定義源文件編碼方式的 declare 語句。所有非 PHP 代碼包括空白符都不能出現(xiàn)在命名空間的聲明之前。

<?php
declare(encoding=&#39;UTF-8&#39;); //定義多個(gè)命名空間和不包含在命名空間中的代碼
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { // 全局代碼
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

以下代碼會(huì)出現(xiàn)語法錯(cuò)誤:

<html>
<?php
    namespace MyProject; // 命名空間前出現(xiàn)了“<html>” 會(huì)致命錯(cuò)誤 - 命名空間必須是程序腳本的第一條語句?>

子命名空間

與目錄和文件的關(guān)系很象,PHP 命名空間也允許指定層次化的命名空間的名稱。因此,命名空間的名字可以使用分層次的方式定義:

<?php
namespace MyProject\Sub\Level;  //聲明分層次的單個(gè)命名空間

const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */  }

?>

上面的例子創(chuàng)建了常量 MyProject\Sub\Level\CONNECT_OK,類 MyProject\Sub\Level\Connection 和函數(shù) MyProject\Sub\Level\Connect。

命名空間使用

PHP 命名空間中的類名可以通過三種方式引用:

非限定名稱,或不包含前綴的類名稱,例如 $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。

下面是一個(gè)使用這三種方式的實(shí)例:

file1.php 文件代碼

<?php
namespace Foo\Bar\subnamespace; 

const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}
?>

file2.php 文件代碼

<?php
namespace Foo\Bar;
include &#39;file1.php&#39;;

const FOO = 2;
function foo() {}
class foo
{
    static function staticmethod() {}
}

/* 非限定名稱 */
foo(); // 解析為 Foo\Bar\foo resolves to function Foo\Bar\foo
foo::staticmethod(); // 解析為類 Foo\Bar\foo的靜態(tài)方法staticmethod。resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // resolves to constant Foo\Bar\FOO

/* 限定名稱 */
subnamespace\foo(); // 解析為函數(shù) Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析為類 Foo\Bar\subnamespace\foo,
                                  // 以及類的方法 staticmethod
echo subnamespace\FOO; // 解析為常量 Foo\Bar\subnamespace\FOO
                                  
/* 完全限定名稱 */
\Foo\Bar\foo(); // 解析為函數(shù) Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析為類 Foo\Bar\foo, 以及類的方法 staticmethod
echo \Foo\Bar\FOO; // 解析為常量 Foo\Bar\FOO
?>

注意訪問任意全局類、函數(shù)或常量,都可以使用完全限定名稱,例如 \strlen() 或 \Exception 或 \INI_ALL。

在命名空間內(nèi)部訪問全局類、函數(shù)和常量:

<?php
namespace Foo;

function strlen() {}
const INI_ALL = 3;
class Exception {}

$a = \strlen(&#39;hi&#39;); // 調(diào)用全局函數(shù)strlen
$b = \INI_ALL; // 訪問全局常量 INI_ALL
$c = new \Exception(&#39;error&#39;); // 實(shí)例化全局類 Exception
?>

命名空間和動(dòng)態(tài)語言特征

PHP 命名空間的實(shí)現(xiàn)受到其語言自身的動(dòng)態(tài)特征的影響。因此,如果要將下面的代碼轉(zhuǎn)換到命名空間中,動(dòng)態(tài)訪問元素。

example1.php 文件代碼:

<?php
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "global";

$a = &#39;classname&#39;;
$obj = new $a; // prints classname::__construct
$b = &#39;funcname&#39;;
$b(); // prints funcname
echo constant(&#39;constname&#39;), "\n"; // prints global
?>

必須使用完全限定名稱(包括命名空間前綴的類名稱)。注意因?yàn)樵趧?dòng)態(tài)的類名稱、函數(shù)名稱或常量名稱中,限定名稱和完全限定名稱沒有區(qū)別,因此其前導(dǎo)的反斜杠是不必要的。

動(dòng)態(tài)訪問命名空間的元素

<?php
namespace namespacename;
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "namespaced";

include &#39;example1.php&#39;;

$a = &#39;classname&#39;;
$obj = new $a; // prints classname::__construct
$b = &#39;funcname&#39;;
$b(); // prints funcname
echo constant(&#39;constname&#39;), "\n"; // prints global

/* note that if using double quotes, "\\namespacename\\classname" must be used */
$a = &#39;\namespacename\classname&#39;;
$obj = new $a; // prints namespacename\classname::__construct
$a = &#39;namespacename\classname&#39;;
$obj = new $a; // also prints namespacename\classname::__construct
$b = &#39;namespacename\funcname&#39;;
$b(); // prints namespacename\funcname
$b = &#39;\namespacename\funcname&#39;;
$b(); // also prints namespacename\funcname
echo constant(&#39;\namespacename\constname&#39;), "\n"; // prints namespaced
echo constant(&#39;namespacename\constname&#39;), "\n"; // also prints namespaced
?>

namespace關(guān)鍵字和__NAMESPACE__常量

PHP支持兩種抽象的訪問當(dāng)前命名空間內(nèi)部元素的方法,__NAMESPACE__ 魔術(shù)常量和namespace關(guān)鍵字。

常量__NAMESPACE__的值是包含當(dāng)前命名空間名稱的字符串。在全局的,不包括在任何命名空間中的代碼,它包含一個(gè)空的字符串。

__NAMESPACE__ 示例, 在命名空間中的代碼

<?php
namespace MyProject;

echo &#39;"&#39;, __NAMESPACE__, &#39;"&#39;; // 輸出 "MyProject"
?>

__NAMESPACE__ 示例,全局代碼

<?php

echo &#39;"&#39;, __NAMESPACE__, &#39;"&#39;; // 輸出 ""
?>

常量 __NAMESPACE__ 在動(dòng)態(tài)創(chuàng)建名稱時(shí)很有用,例如:

使用__NAMESPACE__動(dòng)態(tài)創(chuàng)建名稱

<?php
namespace MyProject;

function get($classname)
{
    $a = __NAMESPACE__ . &#39;\\&#39; . $classname;
    return new $a;
}
?>

關(guān)鍵字 namespace 可用來顯式訪問當(dāng)前命名空間或子命名空間中的元素。它等價(jià)于類中的 self 操作符。

namespace操作符,命名空間中的代碼

<?php
namespace MyProject;

use blah\blah as mine; // see "Using namespaces: importing/aliasing"

blah\mine(); // calls function blah\blah\mine()
namespace\blah\mine(); // calls function MyProject\blah\mine()

namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method "method" of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b
?>

namespace操作符, 全局代碼

<?php

namespace\func(); // calls function func()
namespace\sub\func(); // calls function sub\func()
namespace\cname::method(); // calls static method "method" of class cname
$a = new namespace\sub\cname(); // instantiates object of class sub\cname
$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b
?>

使用命名空間:別名/導(dǎo)入

PHP 命名空間支持 有兩種使用別名或?qū)敕绞剑簽轭惷Q使用別名,或?yàn)槊臻g名稱使用別名。注意PHP不支持導(dǎo)入函數(shù)或常量。

在PHP中,別名是通過操作符 use 來實(shí)現(xiàn)的. 下面是一個(gè)使用所有可能的三種導(dǎo)入方式的例子:

1、使用use操作符導(dǎo)入/使用別名

<?php
namespace foo;
use My\Full\Classname as Another;

// 下面的例子與 use My\Full\NSname as NSname 相同
use My\Full\NSname;

// 導(dǎo)入一個(gè)全局類
use \ArrayObject;

$obj = new namespace\Another; // 實(shí)例化 foo\Another 對(duì)象
$obj = new Another; // 實(shí)例化 My\Full\Classname 對(duì)象
NSname\subns\func(); // 調(diào)用函數(shù) My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // 實(shí)例化 ArrayObject 對(duì)象
// 如果不使用 "use \ArrayObject" ,則實(shí)例化一個(gè) foo\ArrayObject 對(duì)象
?>

2、 一行中包含多個(gè)use語句

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 實(shí)例化 My\Full\Classname 對(duì)象
NSname\subns\func(); // 調(diào)用函數(shù) My\Full\NSname\subns\func
?>

導(dǎo)入操作是在編譯執(zhí)行的,但動(dòng)態(tài)的類名稱、函數(shù)名稱或常量名稱則不是。

3、導(dǎo)入和動(dòng)態(tài)名稱

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 實(shí)例化一個(gè) My\Full\Classname 對(duì)象
$a = &#39;Another&#39;;
$obj = new $a;      // 實(shí)際化一個(gè) Another 對(duì)象
?>

另外,導(dǎo)入操作只影響非限定名稱和限定名稱。完全限定名稱由于是確定的,故不受導(dǎo)入的影響。

4、導(dǎo)入和完全限定名稱

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
$obj = new \Another; // instantiates object of class Another
$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing
$obj = new \Another\thing; // instantiates object of class Another\thing
?>

使用命名空間:后備全局函數(shù)/常量

在一個(gè)命名空間中,當(dāng) PHP 遇到一個(gè)非限定的類、函數(shù)或常量名稱時(shí),它使用不同的優(yōu)先策略來解析該名稱。類名稱總是解析到當(dāng)前命名空間中的名稱。因此在訪問系統(tǒng)內(nèi)部或不包含在命名空間中的類名稱時(shí),必須使用完全限定名稱,例如:

1、在命名空間中訪問全局類

<?php
namespace A\B\C;
class Exception extends \Exception {}

$a = new Exception(&#39;hi&#39;); // $a 是類 A\B\C\Exception 的一個(gè)對(duì)象
$b = new \Exception(&#39;hi&#39;); // $b 是類 Exception 的一個(gè)對(duì)象

$c = new ArrayObject; // 致命錯(cuò)誤, 找不到 A\B\C\ArrayObject 類
?>

對(duì)于函數(shù)和常量來說,如果當(dāng)前命名空間中不存在該函數(shù)或常量,PHP 會(huì)退而使用全局空間中的函數(shù)或常量。

2、 命名空間中后備的全局函數(shù)/常量

<?php
namespace A\B\C;

const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}

echo E_ERROR, "\n"; // 輸出 "45"
echo INI_ALL, "\n"; // 輸出 "7" - 使用全局常量 INI_ALL

echo strlen(&#39;hi&#39;), "\n"; // 輸出 "1"
if (is_array(&#39;hi&#39;)) { // 輸出 "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}
?>

全局空間

如果沒有定義任何命名空間,所有的類與函數(shù)的定義都是在全局空間,與 PHP 引入命名空間概念前一樣。在名稱前加上前綴 \ 表示該名稱是全局空間中的名稱,即使該名稱位于其它的命名空間中時(shí)也是如此。

使用全局空間說明

<?php
namespace A\B\C;

/* 這個(gè)函數(shù)是 A\B\C\fopen */
function fopen() { 
     /* ... */
     $f = \fopen(...); // 調(diào)用全局的fopen函數(shù)
     return $f;
} 
?>

命名空間的順序

自從有了命名空間之后,最容易出錯(cuò)的該是使用類的時(shí)候,這個(gè)類的尋找路徑是什么樣的了。

<?php
namespace A;
use B\D, C\E as F;

// 函數(shù)調(diào)用

foo();      // 首先嘗試調(diào)用定義在命名空間"A"中的函數(shù)foo()
            // 再嘗試調(diào)用全局函數(shù) "foo"

\foo();     // 調(diào)用全局空間函數(shù) "foo" 

my\foo();   // 調(diào)用定義在命名空間"A\my"中函數(shù) "foo" 

F();        // 首先嘗試調(diào)用定義在命名空間"A"中的函數(shù) "F" 
            // 再嘗試調(diào)用全局函數(shù) "F"

// 類引用

new B();    // 創(chuàng)建命名空間 "A" 中定義的類 "B" 的一個(gè)對(duì)象
            // 如果未找到,則嘗試自動(dòng)裝載類 "A\B"

new D();    // 使用導(dǎo)入規(guī)則,創(chuàng)建命名空間 "B" 中定義的類 "D" 的一個(gè)對(duì)象
            // 如果未找到,則嘗試自動(dòng)裝載類 "B\D"

new F();    // 使用導(dǎo)入規(guī)則,創(chuàng)建命名空間 "C" 中定義的類 "E" 的一個(gè)對(duì)象
            // 如果未找到,則嘗試自動(dòng)裝載類 "C\E"

new \B();   // 創(chuàng)建定義在全局空間中的類 "B" 的一個(gè)對(duì)象
            // 如果未發(fā)現(xiàn),則嘗試自動(dòng)裝載類 "B"

new \D();   // 創(chuàng)建定義在全局空間中的類 "D" 的一個(gè)對(duì)象
            // 如果未發(fā)現(xiàn),則嘗試自動(dòng)裝載類 "D"

new \F();   // 創(chuàng)建定義在全局空間中的類 "F" 的一個(gè)對(duì)象
            // 如果未發(fā)現(xiàn),則嘗試自動(dòng)裝載類 "F"

// 調(diào)用另一個(gè)命名空間中的靜態(tài)方法或命名空間函數(shù)

B\foo();    // 調(diào)用命名空間 "A\B" 中函數(shù) "foo"

B::foo();   // 調(diào)用命名空間 "A" 中定義的類 "B" 的 "foo" 方法
            // 如果未找到類 "A\B" ,則嘗試自動(dòng)裝載類 "A\B"

D::foo();   // 使用導(dǎo)入規(guī)則,調(diào)用命名空間 "B" 中定義的類 "D" 的 "foo" 方法
            // 如果類 "B\D" 未找到,則嘗試自動(dòng)裝載類 "B\D"

\B\foo();   // 調(diào)用命名空間 "B" 中的函數(shù) "foo" 

\B::foo();  // 調(diào)用全局空間中的類 "B" 的 "foo" 方法
            // 如果類 "B" 未找到,則嘗試自動(dòng)裝載類 "B"

// 當(dāng)前命名空間中的靜態(tài)方法或函數(shù)

A\B::foo();   // 調(diào)用命名空間 "A\A" 中定義的類 "B" 的 "foo" 方法
              // 如果類 "A\A\B" 未找到,則嘗試自動(dòng)裝載類 "A\A\B"

\A\B::foo();  // 調(diào)用命名空間 "A\B" 中定義的類 "B" 的 "foo" 方法
              // 如果類 "A\B" 未找到,則嘗試自動(dòng)裝載類 "A\B"
?>

名稱解析遵循下列規(guī)則:

對(duì)完全限定名稱的函數(shù),類和常量的調(diào)用在編譯時(shí)解析。例如?new \A\B?解析為類?A\B。

所有的非限定名稱和限定名稱(非完全限定名稱)根據(jù)當(dāng)前的導(dǎo)入規(guī)則在編譯時(shí)進(jìn)行轉(zhuǎn)換。例如,如果命名空間?A\B\C?被導(dǎo)入為C,那么對(duì)?C\D\e()?的調(diào)用就會(huì)被轉(zhuǎn)換為?A\B\C\D\e()。

在命名空間內(nèi)部,所有的沒有根據(jù)導(dǎo)入規(guī)則轉(zhuǎn)換的限定名稱均會(huì)在其前面加上當(dāng)前的命名空間名稱。例如,在命名空間?A\B?內(nèi)部調(diào)用?C\D\e(),則?C\D\e()?會(huì)被轉(zhuǎn)換為?A\B\C\D\e()?。

非限定類名根據(jù)當(dāng)前的導(dǎo)入規(guī)則在編譯時(shí)轉(zhuǎn)換(用全名代替短的導(dǎo)入名稱)。例如,如果命名空間?A\B\C?導(dǎo)入為C,則?new C()被轉(zhuǎn)換為?new A\B\C()?。

在命名空間內(nèi)部(例如A\B),對(duì)非限定名稱的函數(shù)調(diào)用是在運(yùn)行時(shí)解析的。例如對(duì)函數(shù)?foo()?的調(diào)用是這樣解析的:

在當(dāng)前命名空間中查找名為?A\B\foo()?的函數(shù)

嘗試查找并調(diào)用?全局(global)?空間中的函數(shù)?foo()。

在命名空間(例如A\B)內(nèi)部對(duì)非限定名稱或限定名稱類(非完全限定名稱)的調(diào)用是在運(yùn)行時(shí)解析的。下面是調(diào)用?new C()?及new D\E()?的解析過程:?new C()的解析:new D\E()的解析:為了引用全局命名空間中的全局類,必須使用完全限定名稱?new \C()。

在類名稱前面加上當(dāng)前命名空間名稱變成:A\B\D\E,然后查找該類。

嘗試自動(dòng)裝載類?A\B\D\E。

在當(dāng)前命名空間中查找A\B\C類。

嘗試自動(dòng)裝載類A\B\C。


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1502
276