国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PHP命名空間和自動(dòng)加載類

姘存按 / 485人閱讀

摘要:在命名空間內(nèi)部,所有的沒有根據(jù)導(dǎo)入規(guī)則轉(zhuǎn)換的限定名稱均會在其前面加上當(dāng)前的命名空間名稱。為了引用全局命名空間中的全局類,必須使用完全限定名稱。實(shí)際上命名空間和自動(dòng)加載類的結(jié)合就基本是通過路徑形式將命名空間路徑替換為實(shí)際路徑。

背景

最近有個(gè)朋友問我 PHP 命名空間是咋樣的,但是由于長期不做開發(fā),筆者實(shí)際上也已經(jīng)忘得差不多了,所以也回答不出來。只是記得和 Java 挺像的。事后重新查了一下 PHP 的官方文檔,并且和 Java 做對比,Java 的命名空間實(shí)際上來自于 JVM 本身的機(jī)制,JVM 是基于 class 字節(jié)碼文件加載類,由于類很容易出現(xiàn)重名的情況,換言之 class 字節(jié)碼文件也會出現(xiàn)重名情況,所以就需要使用目錄來管理不同的字節(jié)碼文件,而為了保證加載正常,所以就需要命名空間這種機(jī)制。當(dāng)然,也可以說是由于命名空間的存在才有了目錄管理的方式。但是 PHP 和 Java 不一樣,PHP 是一種動(dòng)態(tài)腳本語言,它的代碼分散在所有腳本中,當(dāng)需要的時(shí)候才會使用 include 函數(shù)加載對應(yīng)的文件,所以 PHP 的命名空間,實(shí)際上是基于 PHP 的自動(dòng)加載類,自動(dòng)加載類實(shí)現(xiàn)了才能保證 PHP 命名空間存在的意義。

命名空間概述

命名空間據(jù)筆者所知應(yīng)該最早源于 C++ 語言,在 C++98 標(biāo)準(zhǔn)以后,為了保證各種命名不重合所推出的一種解決方案。現(xiàn)在的面向?qū)ο笳Z言基本都有這種機(jī)制,當(dāng)然除了命名空間以外,還有很多種方式,比如模塊化,不過實(shí)際上這些機(jī)制都是用來解決封裝問題的,所以筆者個(gè)人認(rèn)為并無好壞之分。
先把 PHP 官方文檔代碼拉出來溜溜

非常容易理解的代碼,從上面的代碼中可以看到 PHP 定義的命名空間是怎么樣的,不過筆者個(gè)人認(rèn)為其定義非常反人類,居然使用反斜杠來分隔命名空間路徑。不過有一點(diǎn)需要注意,名為 PHP 或 php 的命名空間,以及以這些名字開頭的命名空間(例如PHPClasses)被保留用作語言內(nèi)核使用,而不應(yīng)該在用戶空間的代碼中使用。

定義命名空間

PHP 命名空間功能只能在 PHP5.3.0 以上版本使用,對于一個(gè)命名空間,只有類、接口、函數(shù)和常量會被包含在命名空間中。

當(dāng)然,也可以使用花括號來包含所有需要的內(nèi)容,就像這樣。

不過這樣很容易造成縮進(jìn)上的問題,所以筆者不推薦使用,并且一般情況下,一個(gè)文件包含一個(gè)類,所以也不需要花括號來分割命名空間范圍。

使用命名空間

對于命名空間路徑來說,存在著三種形式

非限定名稱,或者說不包含前綴的類名稱。例如 $a=new foo();foo::staticmethod();。如果當(dāng)前命名空間是 currentnamespacefoo 將被解析為 currentnamespacefoo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,則 foo 會被解析為foo`。

限定名稱,或包含前綴的名稱,例如 $a = new subnamespacefoo();subnamespacefoo::staticmethod();。如果當(dāng)前的命名空間是 currentnamespace,則 foo 會被解析為 currentnamespacesubnamespacefoo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,foo 會被解析為 subnamespacefoo

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

由于 PHP 本身動(dòng)態(tài)語言的特性,所以完全可以使用字符串動(dòng)態(tài)訪問命名空間內(nèi)的元素。

不過有一點(diǎn)需要注意,就是單雙引號之間的區(qū)別,單引號可以不需要處理 的轉(zhuǎn)譯處理,而雙引號就必須使用 等轉(zhuǎn)譯符號。
Java 語言使用 import 機(jī)制引入命名空間,由于 Java 可以指定到類名,所以 Java 最多只能導(dǎo)入到具體類,而 PHP 則可以指定到一個(gè)命名空間內(nèi)的類、常量、方法等,并且支持命名空間別名。

名稱解析規(guī)則

首先就是前面講過的三種名稱類型,名稱解析遵循以下規(guī)則:

對完全限定名稱的函數(shù),類和常量的調(diào)用在編譯時(shí)解析。例如 new AB 解析為類 AB。

所有的非限定名稱和限定名稱(非完全限定名稱)根據(jù)當(dāng)前的導(dǎo)入規(guī)則在編譯時(shí)進(jìn)行轉(zhuǎn)換。例如,如果命名空間 ABC 被導(dǎo)入為 C,那么對 CDe() 的調(diào)用就會被轉(zhuǎn)換為 ABCDe()。

在命名空間內(nèi)部,所有的沒有根據(jù)導(dǎo)入規(guī)則轉(zhuǎn)換的限定名稱均會在其前面加上當(dāng)前的命名空間名稱。例如,在命名空間 AB 內(nèi)部調(diào)用 CDe(),則 CDe() 會被轉(zhuǎn)換為 ABCDe() 。

非限定類名根據(jù)當(dāng)前的導(dǎo)入規(guī)則在編譯時(shí)轉(zhuǎn)換(用全名代替短的導(dǎo)入名稱)。例如,如果命名空間 ABC 導(dǎo)入為C,則 new C() 被轉(zhuǎn)換為 new ABC() 。

在命名空間內(nèi)部(例如AB),對非限定名稱的函數(shù)調(diào)用是在運(yùn)行時(shí)解析的。例如對函數(shù) foo() 的調(diào)用是這樣解析的:

在當(dāng)前命名空間中查找名為 ABfoo() 的函數(shù)

嘗試查找并調(diào)用 全局(global) 空間中的函數(shù) foo()。

在命名空間(例如AB)內(nèi)部對非限定名稱或限定名稱類(非完全限定名稱)的調(diào)用是在運(yùn)行時(shí)解析的。下面是調(diào)用 new C() 及 new DE() 的解析過程:

new C()的解析:

在當(dāng)前命名空間中查找ABC類。

嘗試自動(dòng)裝載類ABC。

new DE()的解析:

在類名稱前面加上當(dāng)前命名空間名稱變成:ABDE,然后查找該類。

嘗試自動(dòng)裝載類 ABDE。

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

從上面的規(guī)則來看,實(shí)際上 PHP 的導(dǎo)入規(guī)則和 Java 有點(diǎn)類似,但是卻有不一樣,主要是因?yàn)?Java 是完全面向?qū)ο蟮模?PHP 本質(zhì)上還只是一種基于對象的語言。

自動(dòng)加載類

在早期 PHP 開發(fā)中,開發(fā)者最煩的就是一堆 include 函數(shù)包含了一大堆文件,而且早期時(shí)候 PHP 面向?qū)ο蟮母拍畲_實(shí)太差了,因?yàn)?PHP 作為一種腳本語言,不存在程序入口,所以腳本順序化執(zhí)行的誘惑力實(shí)在是很大,即使面向?qū)ο箝_發(fā),但是缺少極佳的模塊劃分導(dǎo)入機(jī)制,代碼可以說很難有美感,最大的代表就是 Wordpress。如果有朋友看過這個(gè)典型項(xiàng)目,可以覺得非常痛苦,因?yàn)楦鞣N初始化、業(yè)務(wù)流程都分散在各個(gè)不同的文件中,使用 include 函數(shù)進(jìn)行銜接,然后每次頁面渲染都是同樣的要走一趟流程。當(dāng)然,這是 Wordpress 的歷史包袱,而在支持老版本 PHP 的情況下 Wordpress 代碼已經(jīng)寫得足夠優(yōu)化了。
在 PHP5 中就不需要這么麻煩了,因?yàn)榭梢远x一個(gè) __autoload() 函數(shù),當(dāng)調(diào)用一個(gè)未定義的類的時(shí)候就會啟動(dòng)此函數(shù),從而在拋出錯(cuò)誤之前做最后的補(bǔ)救,不過這個(gè)函數(shù)的本意已經(jīng)被完全曲解使用了,現(xiàn)在都用來做自動(dòng)加載。
注意,這個(gè)函數(shù)實(shí)際上已經(jīng)不被推薦使用了,相反,現(xiàn)在應(yīng)當(dāng)使用 spl_autoload_register() 來注冊類的自動(dòng)加載函數(shù)。

bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] )

autoload_function 是需要注冊的自動(dòng)裝載函數(shù),如果此項(xiàng)為空,則會注冊 spl_autoload 函數(shù),
throw 此參數(shù)設(shè)置了 autoload_function 無法成功注冊時(shí), spl_autoload_register() 是否拋出異常。
prepend 如果是 true,spl_autoload_register() 會添加函數(shù)到隊(duì)列之首,而不是隊(duì)列尾部。
上面提到了 spl_autoload 函數(shù),實(shí)際上注冊函數(shù)的規(guī)范就應(yīng)當(dāng)遵循此函數(shù),函數(shù)聲明如下:

void spl_autoload ( string $class_name [, string $file_extensions ] )

由于這個(gè)函數(shù)默認(rèn)實(shí)現(xiàn)是通過 C 語言,所以這里給出一個(gè) PHP 語言的實(shí)現(xiàn)規(guī)范。

大致上就和這個(gè)是類似的。實(shí)際上命名空間和自動(dòng)加載類的結(jié)合就基本是通過路徑形式

function __autoload(){
    $dir = "./libralies";
    set_include_path(get_include_path(). PATH_SEPARATOR. $dir);
    $class = str_replace("", "/", $class) . ".php"; 
    require_once($class);
}

將命名空間路徑替換為實(shí)際路徑。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/21491.html

相關(guān)文章

  • PHP自動(dòng)加載功能原理解析

    摘要:前言在開始之前,歡迎關(guān)注我自己的博客這篇文章是對自動(dòng)加載功能的一個(gè)總結(jié),內(nèi)容涉及的自動(dòng)加載功能的命名空間的與標(biāo)準(zhǔn)等內(nèi)容。要實(shí)現(xiàn)第一步,第二步的功能,必須在開發(fā)時(shí)約定類名與磁盤文件的映射方法,只有這樣我們才能根據(jù)類名找到它對應(yīng)的磁盤文件。 前言 在開始之前,歡迎關(guān)注我自己的博客:www.leoyang90.cn 這篇文章是對PHP自動(dòng)加載功能的一個(gè)總結(jié),內(nèi)容涉及PHP的自動(dòng)加載功能、P...

    Imfan 評論0 收藏0
  • Composer的Autoload源碼實(shí)現(xiàn)——啟動(dòng)與初始化

    摘要:任務(wù)是加載類的初始化頂級命名空間與文件路徑映射初始化和注冊。在實(shí)際情況下可能會出現(xiàn)這樣的情況。值得注意的是這個(gè)函數(shù)返回的是一個(gè)匿名函數(shù),為什么呢原因就是類中的等等都是的。。。關(guān)于匿名函數(shù)的綁定功能。 前言 在開始之前,歡迎關(guān)注我自己的博客:www.leoyang90.cn 上一篇文章,我們討論了 PHP 的自動(dòng)加載原理、PHP 的命名空間、PHP 的 PSR0 與 PSR4 標(biāo)準(zhǔn),有...

    MarvinZhang 評論0 收藏0
  • ThinkPHP5.1 源碼淺析(二)自動(dòng)加載機(jī)制

    摘要:如果遍歷后沒有找到,則加載失敗。在之后碰到了之后直接拿來用,提高系統(tǒng)自動(dòng)加載的性能。這里我們就講完了注冊自動(dòng)加載。使用自動(dòng)加載我們在中定義了我們自動(dòng)加載函數(shù)式方法。 繼 生命周期的第二篇,大家盡可放心,不會隨便鴿文章的 第一篇中,我們提到了入口腳本,也說了,里面注冊了自動(dòng)加載的功能 本文默認(rèn)你有自動(dòng)加載和命名空間的基礎(chǔ)。如果沒有請 看此篇文章 php 類的自動(dòng)加載與命名空間 自動(dòng)加載...

    mudiyouyou 評論0 收藏0
  • Composer的Autoload源碼實(shí)現(xiàn)——注冊與運(yùn)行

    前言 在開始之前,歡迎關(guān)注我自己的博客:www.leoyang90.cn上一篇 文章我們講到了 Composer 自動(dòng)加載功能的啟動(dòng)與初始化,經(jīng)過啟動(dòng)與初始化,自動(dòng)加載核心類對象已經(jīng)獲得了頂級命名空間與相應(yīng)目錄的映射,換句話說,如果有命名空間 AppConsoleKernel,我們已經(jīng)知道了 App 對應(yīng)的目錄,接下來我們就要解決下面的就是 ConsoleKernel這一段。 注冊 我們先回顧...

    wanghui 評論0 收藏0
  • 自動(dòng)加載命名空間

    摘要:不傳參數(shù),直接調(diào)用,會默認(rèn)調(diào)用來加載類,如果后面再調(diào)用有傳參數(shù)的,也會失效的如果使用了命名空間,那么會把路徑和類名一同帶過來的。 自動(dòng)加載 兩種實(shí)現(xiàn)方式 1、__autoload(); 2、spl_autoload_register(); (主要使用) __autoload()現(xiàn)在很少使用,因?yàn)槭褂眠@種方式,在一個(gè)系統(tǒng)的實(shí)現(xiàn)中,假如需要使用很多其它的類庫,這些類庫可能是由...

    songjz 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<