茄子在线看片免费人成视频,午夜福利精品a在线观看,国产高清自产拍在线观看,久久综合久久狠狠综合

    <s id="ddbnn"></s>
  • <sub id="ddbnn"><ol id="ddbnn"></ol></sub>

  • <legend id="ddbnn"></legend><s id="ddbnn"></s>

    PHP命名空間和自動(dòng)加載類
    來(lái)源:易賢網(wǎng) 閱讀:1299 次 日期:2016-08-27 13:36:36
    溫馨提示:易賢網(wǎng)小編為您整理了“PHP命名空間和自動(dòng)加載類”,方便廣大網(wǎng)友查閱!

    PHP的命名空間(namespace)是php5.3之后才有的。這篇文章主要介紹了PHP命名空間和自動(dòng)加載類的相關(guān)資料,需要的朋友可以參考下

    PHP的命名空間(namespace)是php5.3之后才有的。這個(gè)概念在C#中已經(jīng)很早就有了,php中的namespace其實(shí)和c#的概念是一樣的。

    為什么php中要使用namespace?

    假設(shè)如果不使用namespace,那么每個(gè)類在一個(gè)項(xiàng)目中的名字就必須是固定的。因?yàn)閜hp在new的時(shí)候不管是調(diào)用autoload還是調(diào)用已加載過(guò)的類,都存在一個(gè)類名對(duì)應(yīng)的文件。所以在沒(méi)有namespace的時(shí)候,我們會(huì)想各種命名規(guī)則來(lái)區(qū)分不同的類,比如project1_school1_class1_Student或者project2_school_class_Student。

    引入namespace之后就可以將這個(gè)有效規(guī)避了,一個(gè)namespace就相當(dāng)于對(duì)應(yīng)一個(gè)文件路徑,查找這個(gè)類的時(shí)候,就會(huì)去對(duì)應(yīng)的文件路徑查找類定義文件了。

    背景

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

    命名空間概述

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

    <?php

    namespace my\name; // 參考 "定義命名空間" 小節(jié)

    class MyClass {}

    function myfunction() {}

    const MYCONST = 1;

    $a = new MyClass;

    $c = new \my\name\MyClass; // 參考 "全局空間" 小節(jié)

    $a = strlen('hi'); // 參考 "使用命名空間:后備全局函數(shù)/常量" 小節(jié)

    $d = namespace\MYCONST; // 參考 "namespace操作符和__NAMESPACE__常量” 小節(jié)

    $d = __NAMESPACE__ . '\MYCONST';

    echo constant($d); // 參考 "命名空間和動(dòng)態(tài)語(yǔ)言特征" 小節(jié)

    ?>

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

    定義命名空間

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

    <?php

    namespace MyProject;

    const CONNECT_OK = 1;

    class Connection { /* ... */ }

    function connect() { /* ... */ }

    ?>

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

    <?php

    declare(encoding='UTF-8');

    namespace MyProject {

    const CONNECT_OK = 1;

    class Connection { /* ... */ }

    function connect() { /* ... */ }

    }

    namespace { // 全局代碼

    session_start();

    $a = MyProject\connect();

    echo MyProject\Connection::start();

    }

    ?>

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

    使用命名空間

    對(duì)于命名空間路徑來(lái)說(shuō),存在著三種形式

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

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

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

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

    <?php

    namespace namespacename;

    class classname

    {

    function __construct()

    {

    echo __METHOD__,"\n";

    }

    }

    function funcname()

    {

    echo __FUNCTION__,"\n";

    }

    const constname = "namespaced";

    include 'example1.php';

    $a = 'classname';

    $obj = new $a; // prints classname::__construct

    $b = 'funcname';

    $b(); // prints funcname

    echo constant('constname'), "\n"; // prints global

    /* note that if using double quotes, "\\namespacename\\classname" must be used */

    $a = '\namespacename\classname';

    $obj = new $a; // prints namespacename\classname::__construct

    $a = 'namespacename\classname';

    $obj = new $a; // also prints namespacename\classname::__construct

    $b = 'namespacename\funcname';

    $b(); // prints namespacename\funcname

    $b = '\namespacename\funcname';

    $b(); // also prints namespacename\funcname

    echo constant('\namespacename\constname'), "\n"; // prints namespaced

    echo constant('namespacename\constname'), "\n"; // also prints namespaced

    ?>

    不過(guò)有一點(diǎn)需要注意,就是單雙引號(hào)之間的區(qū)別,單引號(hào)可以不需要處理 \ 的轉(zhuǎn)譯處理,而雙引號(hào)就必須使用 \\ 等轉(zhuǎn)譯符號(hào)。

    Java 語(yǔ)言使用 import 機(jī)制引入命名空間,由于 Java 可以指定到類名,所以 Java 最多只能導(dǎo)入到具體類,而 PHP 則可以指定到一個(gè)命名空間內(nèi)的類、常量、方法等,并且支持命名空間別名。

    <?php

    namespace foo;

    use My\Full\Classname as Another;

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

    use My\Full\NSname;

    // 導(dǎo)入一個(gè)全局類

    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; // 實(shí)例化 foo\Another 對(duì)象

    $obj = new Another; // 實(shí)例化 My\Full\Classname 對(duì)象

    NSname\subns\func(); // 調(diào)用函數(shù) My\Full\NSname\subns\func

    $a = new ArrayObject(array(1)); // 實(shí)例化 ArrayObject 對(duì)象

    // 如果不使用 "use \ArrayObject" ,則實(shí)例化一個(gè) foo\ArrayObject 對(duì)象

    func(); // calls function My\Full\functionName

    echo CONSTANT; // echoes the value of My\Full\CONSTANT

    ?>

    名稱解析規(guī)則

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

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

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

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

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

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

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

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

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

    new C()的解析:

    在當(dāng)前命名空間中查找A\B\C類。

    嘗試自動(dòng)裝載類A\B\C。

    new D\E()的解析:

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

    嘗試自動(dòng)裝載類 A\B\D\E。

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

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

    自動(dòng)加載類

    在早期 PHP 開(kāi)發(fā)中,開(kāi)發(fā)者最煩的就是一堆 include 函數(shù)包含了一大堆文件,而且早期時(shí)候 PHP 面向?qū)ο蟮母拍畲_實(shí)太差了,因?yàn)?PHP 作為一種腳本語(yǔ)言,不存在程序入口,所以腳本順序化執(zhí)行的誘惑力實(shí)在是很大,即使面向?qū)ο箝_(kāi)發(fā),但是缺少極佳的模塊劃分導(dǎo)入機(jī)制,代碼可以說(shuō)很難有美感,最大的代表就是 Wordpress。如果有朋友看過(guò)這個(gè)典型項(xiàng)目,可以覺(jué)得非常痛苦,因?yàn)楦鞣N初始化、業(yè)務(wù)流程都分散在各個(gè)不同的文件中,使用 include 函數(shù)進(jìn)行銜接,然后每次頁(yè)面渲染都是同樣的要走一趟流程。當(dāng)然,這是 Wordpress 的歷史包袱,而在支持老版本 PHP 的情況下 Wordpress 代碼已經(jīng)寫(xiě)得足夠優(yōu)化了。

    在 PHP5 中就不需要這么麻煩了,因?yàn)榭梢远x一個(gè) __autoload() 函數(shù),當(dāng)調(diào)用一個(gè)未定義的類的時(shí)候就會(huì)啟動(dòng)此函數(shù),從而在拋出錯(cuò)誤之前做最后的補(bǔ)救,不過(guò)這個(gè)函數(shù)的本意已經(jīng)被完全曲解使用了,現(xiàn)在都用來(lái)做自動(dòng)加載。

    注意,這個(gè)函數(shù)實(shí)際上已經(jīng)不被推薦使用了,相反,現(xiàn)在應(yīng)當(dāng)使用 spl_autoload_register() 來(lái)注冊(cè)類的自動(dòng)加載函數(shù)。

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

    autoload_function 是需要注冊(cè)的自動(dòng)裝載函數(shù),如果此項(xiàng)為空,則會(huì)注冊(cè) spl_autoload 函數(shù),

    throw 此參數(shù)設(shè)置了 autoload_function 無(wú)法成功注冊(cè)時(shí), spl_autoload_register() 是否拋出異常。

    prepend 如果是 true, spl_autoload_register() 會(huì)添加函數(shù)到隊(duì)列之首,而不是隊(duì)列尾部。

    上面提到了 spl_autoload 函數(shù),實(shí)際上注冊(cè)函數(shù)的規(guī)范就應(yīng)當(dāng)遵循此函數(shù),函數(shù)聲明如下:

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

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

    <?php

    // Your custom class dir

    define('CLASS_DIR', 'class/')

    // Add your class dir to include path

    set_include_path(get_include_path().PATH_SEPARATOR.CLASS_DIR);

    // You can use this trick to make autoloader look for commonly used "My.class.php" type filenames

    spl_autoload_extensions('.class.php');

    // Use default autoload implementation

    spl_autoload_register();

    ?>

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

    function __autoload(){

    $dir = './libralies';

    set_include_path(get_include_path(). PATH_SEPARATOR. $dir);

    $class = str_replace('\\', '/', $class) . '.php';

    require_once($class);

    }

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

    以上內(nèi)容是小編給大家介紹的PHP命名空間和自動(dòng)加載類,希望對(duì)大家有所幫助!

    更多信息請(qǐng)查看網(wǎng)絡(luò)編程
    易賢網(wǎng)手機(jī)網(wǎng)站地址:PHP命名空間和自動(dòng)加載類
    由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門(mén)公布的正式信息和咨詢?yōu)闇?zhǔn)!

    2026國(guó)考·省考課程試聽(tīng)報(bào)名

    • 報(bào)班類型
    • 姓名
    • 手機(jī)號(hào)
    • 驗(yàn)證碼
    關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢 | 簡(jiǎn)要咨詢須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
    工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
    云南網(wǎng)警備案專用圖標(biāo)
    聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
    云南網(wǎng)警報(bào)警專用圖標(biāo)