有關於PHP關鍵特性之命名空間的一些看法! ! !

慕斯
發布: 2023-04-10 06:54:01
轉載
1978 人瀏覽過

你知道命名空間主要是為了解決程式碼中類別和函數可能存在衝突的問題的嗎?而這個特性其他語言一早就有,PHP則是姍姍來遲,它的出現催生了 PSR-4 的誕生,從而也催生了 Composer 的興起,所以是非常重要的特性。

有關於PHP關鍵特性之命名空間的一些看法! ! !

命名空間的定義

命名空間是一個容器,這個容器主要是為了辨識其下的類別和函數。一旦定義了命名空間,它下面的程式碼就屬於這個命名空間了,所以命名空間的定義要在程式碼的最開始行。

對於同一個套件來說,同一個命名空間或子命名空間的程式碼沒有必要在一個PHP 檔案中定義,子命名空間下的程式碼是為了完成特定模組的工作,組合起來就是一個包完整的命名空間。

假如寫的程式碼沒有定義命名空間,那表示它屬於全域的命名空間(\ 符號),所以能夠直接引用類別或函數(不用加 \ 符號)。

引用命名空間識別碼的三種方式

(1)Fully-qualified name

類似於作業系統上的絕對路徑,而且是完整的路徑,所以在理解的時候不會有誤解。
例如在 new \A\B\C ,那麼 C 就會被會解析到 A\B 命名空間下的 C 類別。

(2)Qualified name

類似於作業系統上的相對路徑,它包含部分名字並被引用到目前的命名空間。
例如 B\C() 在命名空間 A 下調用,則最終引用的命名空間就是 A\B\C()。

(3)Unqualified name

類似Qualified name,但沒包含子命名空間。
例如 C() 在命名空間 A\B 下調用,則最終引用的命名空間就是 A\B\C()。

透過一個例子來說明三種引用方式:

namespace \Example;
require_once "fnction.php";
class ClassA {}
function Function() {}

//完全限定名称
\Example\Function();
\Example\B\Function(); 

//限定名称
B\Function(); //指向 \Example\B\Function();

//非限定名称
$test = new ClassA(); //resolves to \Example\ClassA
Function(); //指向 \Example\Function
登入後複製

注意:

  • Inside a namespace,假如在current scope 沒有發現函數和常數的定義,PHP 不會報錯。而是去全域命名空間中尋找。
  • Inside a namespace,假如在current scope 沒有發現類的定義,則PHP 會直接報錯,不會去全局域中找對應的類,所以假如你需要引用一個internal 或用戶自定義的類,必須使用完全限定名稱。

先舉個簡單的例子,先寫一段程式碼(定義在命名空間下),命名為function.php :

namespace Foo\Bar\subnamespace;
const FOO = 1;
function foo() 
{
    return "foo\r\n";
}
class foo 
{
    static function staticmethod()
    {
        return __METHOD__ . "\r\n" ;
    }

    function foofunction()
    {
        return __METHOD__ . "\r\n" ;
    }
}
登入後複製

再寫一段程式碼test.php,也是處於命名空間之下的程式碼:

namespace secondsp;
include 'function.php';

class foo
{
    function foofunction()
    {
        return __METHOD__ . "\r\n" ;
    }
}

function is_file($file)
{
    return true ;
}
 
//非限定名称:实例化secondsp\foo类对象
$obj = new foo;  
echo $obj->foofunction();

//实例化Foo\Bar\subnamespace\foo 类对象
$obj = new Foo\Bar\subnamespace\foo ;
echo $obj->foofunction();

//代码会报错,在命名空间内部,假如无法找到当前命名空间下的类,则会报错
//$obj = new ArrayObject(array(1)); 
$obj = new \ArrayObject(array(1)); 

//在命名空间内部,假如无法找到当前命名空间下的函数或者常量,则会寻找 native function
echo  strlen("nihao");

 //引用当前命名空间下的函数
var_dump(is_file('nihao')); //True
//引用全局函数
var_dump(\is_file('nihao')); //False
登入後複製

導入,別名

#假如要使用的命名空間層級很長且數量很多,那麼在使用的時候特別麻煩,所以可以使用use 關鍵字匯入命名空間、類別、常數、函數等,然後可以使用它們直接引用完整的名稱。而 alias 關鍵字可以為導入的類別和函數等重命名。

舉例如何使用use 關鍵字,程式碼處於全域命名空間之下:

include 'function.php';

use Foo\Bar\subnamespace\foo ;
$obj = new foo;
echo $obj->foofunction();

use Foo\Bar\subnamespace\foo  as aliasfunname;
$obj = new aliasfunname;
echo $obj->foofunction();
 
use Foo\Bar\subnamespace ; 
$obj = new subnamespace\foo ;
echo $obj->foofunction();

use Foo\Bar\subnamespace  as aliasname;
$obj = new aliasname\foo ;
echo $obj->foofunction();

//由于调用代码并不在命名空间内,所以对于全局的类,无需引入使用
$obj = new ArrayObject(array(1)); 

//导入一个函数
use function Foo\Bar\subnamespace\foo   ;
echo foo();
 
use function Foo\Bar\subnamespace\foo  as func;
echo func();
 
use const  Foo\Bar\subnamespace\FOO;
//echo FOO;
登入後複製

總結:

  • 和Python不一樣,PHP 中的命名空間是語義上的一種概念,和具體程式碼的位置、佈局沒有關係,換句話說,使用命名空間的程式碼需要自己引入庫檔案(所有檔案),至於程式庫檔案如何組織無所謂;而在Python 中,假如模組或套件中有一個__init__.py 文件,則Python 解析器會自動引入套件或所有模組的檔案。
  • PHP 中作用域的概念很弱化,全域和局部域分的很清楚,例如在函數或類別中無法引用全域空間中的變數。而在命名空間則不同,定義命名空間的程式碼,假如找不到對應命名空間下的常數和函數,則會使用全域的常數和函數;而假如找不到對應名命名空間下的類別(包括自定義類別),則代碼直接報錯。
  • 透過 use 關鍵字使用命名空間的,無須透過完全限定名稱的方式(\ 符號)導入,因為 PHP 已經假設導入的是完全限定的命名空間。
  • 透過 use 關鍵字可以匯入常數、函數、類別、介面、其他命名空間。
  • 命名空間是一種語言特性,為了追求更有效的使用,應該有一個使用規範和自動載入機制,這就是 PSR-4 規範。

推薦學習:《PHP影片教學

以上是有關於PHP關鍵特性之命名空間的一些看法! ! !的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:jianshu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!