首頁 >後端開發 >PHP問題 >小編帶你學命名空間的呼叫順序

小編帶你學命名空間的呼叫順序

醉折花枝作酒筹
醉折花枝作酒筹原創
2021-07-30 16:31:081681瀏覽

上一篇文章中我們了解了存取命名空間內部元素,有需要的請看《小編帶你了解如何存取命名空間內部元素(php版)》。這次我們向大家介紹命名空間的順序,有需要的可以參考參考。

首先讓我們來看一個小例子。

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

// 函数调用

foo();      // 首先尝试调用定义在命名空间"A"中的函数foo()
            // 再尝试调用全局函数 "foo"

\foo();     // 调用全局空间函数 "foo" 

my\foo();   // 调用定义在命名空间"A\my"中函数 "foo" 

F();        // 首先尝试调用定义在命名空间"A"中的函数 "F" 
            // 再尝试调用全局函数 "F"

// 类引用

new B();    // 创建命名空间 "A" 中定义的类 "B" 的一个对象
            // 如果未找到,则尝试自动装载类 "A\B"

new D();    // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
            // 如果未找到,则尝试自动装载类 "B\D"

new F();    // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
            // 如果未找到,则尝试自动装载类 "C\E"

new \B();   // 创建定义在全局空间中的类 "B" 的一个对象
            // 如果未发现,则尝试自动装载类 "B"

new \D();   // 创建定义在全局空间中的类 "D" 的一个对象
            // 如果未发现,则尝试自动装载类 "D"

new \F();   // 创建定义在全局空间中的类 "F" 的一个对象
            // 如果未发现,则尝试自动装载类 "F"

// 调用另一个命名空间中的静态方法或命名空间函数

B\foo();    // 调用命名空间 "A\B" 中函数 "foo"

B::foo();   // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
            // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"

D::foo();   // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
            // 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"

\B\foo();   // 调用命名空间 "B" 中的函数 "foo" 

\B::foo();  // 调用全局空间中的类 "B" 的 "foo" 方法
            // 如果类 "B" 未找到,则尝试自动装载类 "B"

// 当前命名空间中的静态方法或函数

A\B::foo();   // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"

\A\B::foo();  // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"
?>

仔細觀察上面的小例子,我們可以觀察到什麼?噹噹,我們現在就給出答案。

在函數呼叫的時候,如果我們只寫了“foo()”,先呼叫的命名空間中的函數,然後在呼叫全域函數;但如果是“\foo()”,這就只呼叫全域函數了。

在類別應用程式的時候,如果我們寫了“new B();”,將會建立命名空間中定義的類別"B"的一個對象,但如果找不到,則嘗試自動裝載類別"A\B"。

在呼叫另一個命名空間中的靜態方法或命名空間函數的時候,如何我們寫了“B\foo()”,這表示我們將呼叫命名空間中的函數「foo()」;但如果寫的是「B::foo();」就不一樣了,他先呼叫命名空間中的函數「foo() ”,但如果未找到,則嘗試自動裝載類別"A\B"。

在目前命名空間中的靜態方法或函數的時候,如何我們寫了“A\B::foo();”,這表示我們會呼叫命名空間"A \A" 中定義的類別"B" 的"foo" 方法,在沒有找到的情況下,自動裝載類別"A\A\B"。

現在讓我們來歸納。

  • 完全限定函數、類別和常數的呼叫將會在編譯的時候解析。例如,new\a\B解析為類別a\B。

  • 所有的非限定名稱和限定名稱(非完全限定名稱)根據目前的導入規則在編譯的時候進行轉換。例如,如果命名空間 A\B\C 被匯入為 C,那麼對 C\D\e() 的呼叫就會轉換為 A\B\C\D\e()。

  • 所有非限定名和限定名(非完全限定名)都在編譯時根據目前導入規則進行轉換。例如,如果命名空間a\B\C作為C導入,則對C​​\D\e()的呼叫將轉換為a\B\C\D\e()。

  • 非限定類別名稱在編譯時會根據目前導入規則進行轉換(將短導入名替換為全名)。例如,如果命名空間a\B\C作為C導入,則新的C()將轉換為新的a\B\C()。

  • 在命名空間(例如,a\b)中,對非限定名稱的函數呼叫在執行時間解析。例如,對函數foo()的呼叫解析如下:

    • 在目前命名空間中尋找名為A\B\foo() 的函數

    • 嘗試尋找並呼叫全域(global) 空間中的函數foo()。

  • 對命名空間(如a\b)內的非限定名稱或限定名類別(非完全限定名)的呼叫在執行時解析。以下是呼叫new c()和new d\e()的解析過程:解析new c():

    • 在目前命名空間中尋找A\B\C類。

    • 嘗試自動裝載類別A\B\C。

  • new D\E()的解析:

    • #在類別名稱前面加上目前命名空間名稱變成:A\B\D\E,然後找出該類別。

    • 嘗試自動裝載類別 A\B\D\E。

  • 為了引用全域命名空間中的全域類,必須使用完全限定名稱 new \C()。

就說到這裡了,有其他想知道的,可以點選這個喔。 → →php影片教學

#

以上是小編帶你學命名空間的呼叫順序的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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