天天看點

PHP命名空間筆記

此篇文章作為我從開始學習php到工作一段時間後的命名空間知識點總結,會随學習和工作的提高而完善

【1】命名空間

定義命名空間意義

一:為了解決多檔案中(互相引入時)類名,常量名,函數名可能會重複命名的問題

二:快速定位檔案位置

三:就是給檔案加個隐式字首

四:命名空間需要寫在檔案的最前面

【2】全局空間

如果沒有定義任何命名空間,所有的類與函數的定義都是在全局空間,與 PHP 引入命名空間概念前一樣。

在名稱前加上字首 \ 表示該名稱是全局空間中的名稱,即使該名稱位于其它的命名空間中時也是如此。 

可類比Linux的根木錄/

【3】一個檔案多個命名空間

按定義名稱了解即可

定義方式:按上下文順序書寫

a.php

namespace:xxx

代碼1

namespace:yyy

代碼2

當然,多個檔案的命名空間也可相同

【4】非限定名稱:

為本檔案定義命名空間後

調用本檔案内的函數,類,變量時,系統預設從本檔案内的命名空間查找

對應的名稱的函數,類,變量

例如 

$a=new foo(); 
//或
$a=foo::staticmethod();
 //如果目前命名空間是currentnamespace,foo 将被解析為 currentnamespace\foo
           

【5】限定名稱

//限定名稱,或包含字首的名稱,例如
 $a = new subnamespace\foo(); 
//或
 subnamespace\foo::staticmethod();
//如果目前的命名空間是 currentnamespace,則 foo 會被解析為 currentnamespace\subnamespace\foo
           

【6】完全限定名稱

//完全限定名稱,或包含了全局字首操作符的名稱,例如
$a = new \currentnamespace\foo(); 
//或 
           
\currentnamespace\foo::staticmethod();
           
//在這種情況下,foo 總是被解析為代碼中的文字名(literal name)currentnamespace\foo
           

就我個人而言,完全限定名稱使用頻率最多,它從全局空間\出發,描述了調用類,方法,常量相對全局的位置,定位精确

額外細節

如果在目前【命名空間】中使用某一個類,預設優先級是目前空間查找并使用,;

所有要在目前命名空間内使用且不屬于目前空間的類,需要先導入一下該類,比如PDO這個php的擴充類

<?php
           
//a.php中
           
namespace app;
$pdo = new \PDO();//此處通過完全限定名稱導入全局空間的pdo類,該類被内置于php的pdo擴充中
           

函數和常量有所不同

函數常量執行的機制:先在目前空間查找,如果沒有找到則退而使用全局空間的函數、常量(php内部自動按優先級查詢),面向對象的程式設計過程中基本都是類對象式的調用,函數和常量設計較少

【7】導入命名空間

通常來說使用完全限定名稱的時候會面臨需要前面寫一大長串的完全限定名稱的麻煩,尤其在一個類多個方法裡多次調用時,這裡就引出了導入的概念

允許通過别名引用或導入外部的完全限定名稱,是命名空間的一個重要特征。這有點類似于在類 unix 檔案系統中可以建立對其它的檔案或目錄的符号連接配接

下方例子引自php官方手冊

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

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

// 導入一個全局類
use ArrayObject;

// importing a function (PHP 5.6+)
use function My\Full\functionName;

// aliasing a function (PHP 5.6+)
use function My\Full\functionName as func;

// importing a constant (PHP 5.6+)
use const My\Full\CONSTANT;

$obj = new namespace\Another; // 執行個體化 foo\Another 對象
$obj = new Another; // 執行個體化 My\Full\Classname 對象
NSname\subns\func(); // 調用函數 My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // 執行個體化 ArrayObject 對象
// 如果不使用 "use \ArrayObject" ,則執行個體化一個 foo\ArrayObject 對象
func(); // calls function My\Full\functionName
echo CONSTANT; // echoes the value of My\Full\CONSTANT
?>
           

為了簡化操作,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
?>
           

為了解決require檔案後調用其中類,函數方法每次調用時都要加載完全限定名稱

我們使用了導入解決,換言之,導入可有可無,但有了可以簡化操作(非常簡化!強烈推薦使用)

導入操作是在編譯執行的,但動态的類名稱、函數名稱或常量名稱則不是。

一些重要細節:

有了命名空間後,我們如果還是想之前那樣require了含有命名空間的檔案

直接調用require過來的代碼是會出錯的

必須先使用空間或者導入空間後才能使用

命名空間的動态語言特性

命名空間可以儲存到變量中,這就展現了動态語言的特性

如果把命名空間儲存到變量中的話,必須使用完全限定名稱,

由于限定名稱和完全限定名稱沒有差別,是以其前導的反斜杠是不必要的。