1. 程式人生 > 程式設計 >PHP 名稱空間原理與用法詳解

PHP 名稱空間原理與用法詳解

本文例項講述了PHP 名稱空間原理與用法。分享給大家供大家參考,具體如下:

名稱空間適用於 (PHP 5 >= 5.3.0,PHP 7)

使用名稱空間基礎

PHP 名稱空間類似於檔案系統,

在檔案系統中訪問一個檔案有三種方式:

  1. 相對檔名形式如foo.txt。它會被解析為currentdirectory/foo.txt,其中 currentdirectory 表示當前目錄。因此如果當前目錄是/home/foo,則該檔名被解析為/home/foo/foo.txt
  2. 相對路徑名形式如subdirectory/foo.txt。它會被解析為currentdirectory/subdirectory/foo.txt
  3. 絕對路徑名形式如/main/foo.txt。它會被解析為/main/foo.txt

PHP 名稱空間中的元素使用同樣的原理。例如,類名可以通過三種方式引用:

  1. 非限定名稱,或不包含字首的類名稱,例如$a=new foo();foo::staticmethod();。如果當前名稱空間是currentnamespace,foo 將被解析為currentnamespace\foo。如果使用 foo 的程式碼是全域性的,不包含在任何名稱空間中的程式碼,則 foo 會被解析為foo。警告:如果名稱空間中的函式或常量未定義,則該非限定的函式名稱或常量名稱會被解析為全域性函式名稱或常量名稱。
  2. 限定名稱,或包含字首的名稱,例如$a = new subnamespace\foo();subnamespace\foo::staticmethod();。如果當前的名稱空間是currentnamespace,則 foo 會被解析為currentnamespace\subnamespace\foo。如果使用 foo 的程式碼是全域性的,不包含在任何名稱空間中的程式碼,foo 會被解析為subnamespace\foo
  3. 完全限定名稱,或包含了全域性字首操作符的名稱,例如,$a = new \currentnamespace\foo();\currentnamespace\foo::staticmethod();
    。在這種情況下,foo 總是被解析為程式碼中的文字名(literal name)currentnamespace\foo

定義名稱空間

雖然任意合法的PHP程式碼都可以包含在名稱空間中,但只有以下型別的程式碼受名稱空間的影響,

它們是:

  • 類(包括抽象類和traits)
  • 介面
  • 函式
  • 常量

名稱空間通過關鍵字namespace來宣告。如果一個檔案中包含名稱空間,它必須在其它所有程式碼之前宣告名稱空間,除了一個以外:declare關鍵字。

<html>
<?php
namespaceMyProject;//致命錯誤- 名稱空間必須是程式指令碼的第一條語句
?>

Example 宣告單個名稱空間

<?php
namespace MyProject;

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

?>

在同一個檔案中定義多個名稱空間

定義多個名稱空間,推薦用大括號語法

<?php
namespace MyProject {
  const CONNECT_OK = 1;
  class Connection { /* ... */ }
  function connect() { /* ... */ }
}

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

在實際的程式設計實踐中,非常不提倡在同一個檔案中定義多個名稱空間。這種方式的主要用於將多個 PHP 指令碼合併在同一個檔案中。

將全域性的非名稱空間中的程式碼與名稱空間中的程式碼組合在一起,只能使用大括號形式的語法。全域性程式碼必須用一個不帶名稱的 namespace 語句加上大括號括起來,例如:

<?php
declare(encoding='UTF-8');
namespace MyProject {

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

namespace { // 全域性程式碼
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

namespace關鍵字和__NAMESPACE__常量

常量__NAMESPACE__的值是包含當前名稱空間名稱的字串。

如果不包括在任何名稱空間中的程式碼,則為一個空的字串。

<?php
namespace MyProject;

echo '"',__NAMESPACE__,'"'; // 輸出 "MyProject"
?>
<?php
echo'"','"';//輸出""
?>

關鍵字namespace可用來顯式訪問當前名稱空間或子名稱空間中的元素。它等價於類中的self操作符。

<?php
namespace MyProject;

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

blah\mine(); // calls function MyProject\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
?>

使用名稱空間:別名/匯入

允許通過別名引用或匯入外部的完全限定名稱,是名稱空間的一個重要特徵。這有點類似於在類 unix 檔案系統中可以建立對其它的檔案或目錄的符號連線。

在PHP中,別名是通過操作符use來實現的.

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

$obj = new Another; // 例項化 My\Full\Classname 物件
NSname\subns\func(); // 呼叫函式 My\Full\NSname\subns\func
?>

全域性空間

如果沒有定義任何名稱空間,所有的類與函式的定義都是在全域性空間,與 PHP 引入名稱空間概念前一樣。在名稱前加上字首 \ 表示該名稱是全域性空間中的名稱,即使該名稱位於其它的名稱空間中時也是如此。

<?php
namespace A\B\C;

/* 這個函式是 A\B\C\fopen */
function fopen() { 
 /* ... */
 $f = \fopen(...); // 呼叫全域性的fopen函式
 return $f;
} 
?>

使用名稱空間:後備全域性函式/常量

在一個名稱空間中,當 PHP 遇到一個非限定的類、函式或常量名稱時,它使用不同的優先策略來解析該名稱。

類名稱總是解析到當前名稱空間中的名稱。因此在訪問系統內部或不包含在名稱空間中的類名稱時,必須使用完全限定名稱,

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

$a = new Exception('hi'); // $a 是類 A\B\C\Exception 的一個物件
$b = new \Exception('hi'); // $b 是類 Exception 的一個物件

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

對於函式和常量來說,如果當前名稱空間中不存在該函式或常量,PHP 會退而使用全域性空間中的函式或常量。

<?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('hi'),"\n"; // 輸出 "1"
if (is_array('hi')) { // 輸出 "is not array"
 echo "is array\n";
} else {
 echo "is not array\n";
}
?>

PHP 官方文件:

http://php.net/manual/zh/language.namespaces.php

更多關於PHP相關內容感興趣的讀者可檢視本站專題:《php面向物件程式設計入門教程》、《PHP陣列(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運算與運算子用法總結》、《php字串(string)用法總結》、《php+mysql資料庫操作入門教程》及《php常見資料庫操作技巧彙總》

希望本文所述對大家PHP程式設計有所幫助。