首頁  >  文章  >  後端開發  >  PHP中的命名空間定義與使用(實例詳解)

PHP中的命名空間定義與使用(實例詳解)

WBOY
WBOY原創
2021-10-25 15:29:164384瀏覽

在之前的文章中為大家帶來了《怎麼去搞定PHP類別的繼承? (總結分享)》,其中詳細介紹了在PHP類別中有關繼承的相關知識,本篇我們繼續來看一下PHP命名空間的相關知識,希望對大家有幫助!

PHP中的命名空間定義與使用(實例詳解)

命名空間其實是個抽象的概念,舉個例子,在我們日常生活中,作業系統中目錄用來將相關檔案分組,對於目錄中的檔案來說,它就扮演了命名空間的角色。

那麼什麼是命名空間呢? 其實,命名空間可以理解為封裝事物的方法,在PHP中的類別、函數、常數是不能夠同名的,為了不讓他們同名,解決三者的同名問題,所以需要用到命名空間。

在PHP中,命名空間主要用來解決使用者寫的程式碼與PHP內部或第三方的類別、函數、常數之間的命名衝突,檔案太多的時候總會有可能命名會重複;還有為很長的識別符名稱創建一個很簡短的名稱,這樣的話會提高程式碼的可讀性。

那麼命名空間是怎麼宣告也就是定義和使用的呢?接下來我們來看看應該如何定義命名空間吧!

定義命名空間

在PHP中任意正確的程式碼都可以包含在命名空間中,但只有類別、函數、常數等類型的程式碼才會收到命名空間的影響。

我們透過namespace關鍵字來完成命名空間的定義,它的語法格式如下:

namespace 命名空间名;

範例如下:

<?php  
// 定义代码在 &#39;named&#39; 命名空间中  
namespace named;    //在这里可以不使用大括号
 
// ... 代码 ...  
?>
  • 定義兩個命名空間:

#
<?php
namespace MyProject {    //这里建议大家使用大括号,这里定义了一个名为MyProject的命名空间
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}
namespace Another {   //这里定义了一个名为Another的命名空间
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}
?>
  • 定義子命名空間

PHP中的命名空間與目錄和檔案的關係是很像的,可以允許指定層次化的命名空間名稱。因此,命名空間的名字可以使用分層的方式來定義,它的語法格式如下:

namespace App\Model;
namespace App\Controller\Home;

示例如下:

<?php
namespace MyProject\Sub\Level;  //声明分层次的单个命名空间
const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */  }
?>

在上述事例中,創建了常數MyProject\Sub\Level\CONNECT_OK,類別MyProject\Sub\Level\Connection 和函數MyProject\Sub\Level\Connect

  • #在同一個檔案中,定義多個命名空間

我們有兩種語法格式可以在一個檔案中定義多個命名空間,範例如下:

首先就是簡單的語法組合

<?php
    namespace named;
    const CONNECT_OK = 1;
    class className {
        /* ... */
    }
    namespace names;
    const CONNECT_OK = 1;
    class className {
        /* ... */
    }
?>

然後就是大括號{}

<?php
    namespace named{
        const CONNECT_OK = 1;
        class className {
            /* ... */
        }
    }
    namespace names{
        const CONNECT_OK = 1;
        class className {
            /* ... */
        }
    }
?>

透過上述的介紹,我們已經知道了應該如何定義命名空間,只是定義命名空間還不夠,我們在PHP中使用它才是比較重要的,那接下來看一下應該如何使用命名空間。

使用命名空間

在了解應該如何使用命名空間之前,我們應該要了解的是在PHP中是怎麼知道要是用哪一個命名空間中的元素的,這時候我們就需要知道PHP中命名空間元素訪問的原理了。首先PHP中的我們不太清楚,但是檔案系統我們可以總結出存取檔案的三種方式:

相對檔案名稱、相對路徑名稱和絕對路徑名稱。

PHP命名空間的元素只用同樣的原理,例如命名空間下的類別名稱可以透過三種方式引出:

  • 非限定名稱,或不包含前綴的類別名稱,例如$a = new test()test,如果目前命名空間是currentnamespace,那麼test將被解析為currentnamespace\test。如果test的程式碼是全域的,不包含任何命名空間中的程式碼,那麼test會被解析為test。

  • 限定名稱,或包含前綴名稱,例如$a = new subnamespace\test(),如果目前命名空間是currentnamespace,則test 會被解析為currentnamespace\subnamespace\test#,如果test的程式碼是全域的,不包含任何命名空間中的程式碼,那麼test會被解析為 subnamespace\foo

  • 完全限定名稱,或包含了全域前綴運算子的名稱,例如$a = new \currentnamespace\test(),在這種情況下,test 總是被解析為程式碼中的文字名稱 currentnamespace\test

下面是使用這三種方式的實例,我們需要兩個PHP 原始文件,分別是demo.php index.php,範例程式碼如下:

<?php
    namespace Test\Bar\Demo;
    const FOO = 1;
    function foo() {}
    class foo
    {
        public function demo() {
            echo &#39;命名空间为:Test\Bar\Demo&#39;;
        }
    }
?>
<?php
    namespace Foo\Bar;
    include &#39;Demo.php&#39;;
    const FOO = 2;
    function foo() {
        echo &#39;Foo\Bar 命名空间下的 foo 函数<br>&#39;;
    }
    class foo
    {
        static function demo(){
            echo &#39;命名空间为:Foo\Bar<br>&#39;;
        }
    }
    /* 非限定名称 */
    foo();                  // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo
    foo::demo();            // 解析为类 Foo\Bar\foo 的静态方法 staticmethod。
    echo FOO.&#39;<br>&#39;;        // 解析为常量 Foo\Bar\FOO
    /* 限定名称 */
    Demo\foo();             // 解析为函数 Foo\Bar\Demo\foo
    Demo\foo::demo();       // 解析为类 Foo\Bar\Demo\foo,
                            // 以及类的方法 demo
    echo Demo\FOO.&#39;<br>&#39;;   // 解析为常量 Foo\Bar\Demo\FOO
                                     
    /* 完全限定名称 */
    \Foo\Bar\foo();         // 解析为函数 Foo\Bar\foo
    \Foo\Bar\foo::demo();   // 解析为类 Foo\Bar\foo, 以及类的方法 demo
    echo \Foo\Bar\FOO.&#39;<br>&#39;; // 解析为常量 Foo\Bar\FOO
?>

在上述事例中,我們需要注意的是,存取任意全域類別、函數或常數,都可以使用完全限定名稱,例如\strlen()\Exception 等。

别名、导入

PHP 允许通过别名引用或导入的方式来使用外部的命名空间,这是命名空间的一个重要特征。

在PHP中,通过use关键字和as配合可以实现命名空间的导入和设置别名。它的语法格式如下:

use 命名空间 as 别名;

示例如下:

<?php
    namespace foo;
    use My\Full\Classname as Another;
    // 下面的例子与 use My\Full\NSname as NSname 相同
    use My\Full\NSname;
    // 导入一个全局类
    use ArrayObject;
    // 导入一个函数
    use function My\Full\functionName;
    // 导入一个函数并定义别名
    use function My\Full\functionName as func;
    // 导入一个常量
    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();                         // 调用 My\Full\functionName 函数
    echo CONSTANT;                  // 打印 My\Full\CONSTANT 常量
?>

其中需要注意的是,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。

大家如果感兴趣的话,可以点击《PHP视频教程》进行更多关于PHP知识的学习。

以上是PHP中的命名空間定義與使用(實例詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn