真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PHP命名空間與類自動加載的實現(xiàn)方法

這篇文章主要講解了“PHP命名空間與類自動加載的實現(xiàn)方法”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“PHP命名空間與類自動加載的實現(xiàn)方法”吧!

將樂網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,將樂網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為將樂上1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的將樂做網(wǎng)站的公司定做!

 

1、從文件引入談起

在 PHP 5.3 之前,要在一個 PHP 腳本中引入另一個 PHP 腳本中定義的代碼(通常是函數(shù)或者類),需要借助 include、require、include_once、require_once 等語句,include 和 require 都可以通過指定路徑引入一個 PHP 腳本,區(qū)別是 include 沒有找到對應(yīng)路徑腳本時發(fā)出警告(E_WARNING),而 require 會拋出致命錯誤(E_COMPILE_ERROR),include_once/require_once 也是用于引入指定路徑 PHP 腳本,與 include/require 的區(qū)別是如果指定路徑已經(jīng)包含過,不會再次包含,換言之,只會包含一次同一路徑腳本,include_once 和 require_once 的區(qū)別與 include/require 一樣。

所以從性能角度說,使用 include_once/require_once 性能更好一些,至于使用 include_once 還是 require_once,取決于你對指定路徑 PHP 腳本不存在的預(yù)期處理。

在前面的作業(yè)中,我們已經(jīng)多次使用過它們來引入其他 PHP 腳本文件,比如在博客項目入口文件 index.php 中,我們通過如下代碼引入 bootstrap.php 以便引入初始化函數(shù) bootApp 進行調(diào)用:

require_once 'bootstrap.php';

// 新增一個 IoC 容器,通過依賴注入獲取對象實例
$container = Container::getInstance();
bootApp($container);

...
 

然后在 bootstrap.php 中,又通過如下代碼引入 Container 類定義:

require_once 'core/Container.php';

...
   
自動加載類文件

對于類文件的引入,如果你覺得反復(fù)編寫 require_once/include_once 語句太麻煩,還可以借助 spl_auto_register 函數(shù)注冊自動加載器,實現(xiàn)系統(tǒng)未定義類或接口的自動加載。

比如我們將上述 bootstrap.php 中的通過 require_once 引入 Container 類代碼調(diào)整為通過 spl_autoload_register 函數(shù)自動注冊:

spl_autoload_register(function ($className) {
    require_once 'core/' . $className. '.php';
});
 

這樣,我們只需要通過 spl_autoload_register 全局注冊這個匿名函數(shù)即可,當 Container 類找不到時,會根據(jù)這個自動加載器進行加載。

 

2、命名空間及其使用

結(jié)合 require_once/include_oncespl_autoload_register,已經(jīng)可以很好地解決多個 PHP 腳本之間引入和組合的問題,從而構(gòu)建出復(fù)雜系統(tǒng),比如 Web 開發(fā)框架,或者第三方庫等,事實上,在 PHP 5.3 之前,第三方框架和庫就是這么做的,不過,細心的同學可能已經(jīng)看出來,spl_autoload_register 這種自動類加載機制存在一個問題,那就是不同庫/組件類名沖突問題,因此,從 PHP 5.3 開始,引入了命名空間的概念,通過命名空間,可以很好的解決這個問題,而且相較于前者,代碼可讀性更好。

在 PHP 中,通過 namespace 關(guān)鍵字聲明當前腳本所在的命名空間,通常,一個 PHP 腳本文件歸屬于一個命名空間。我們在 php_learning 目錄下新建一個 ns 子目錄存放本篇教程代碼,然后在 ns 目錄下創(chuàng)建一個 Test.php 文件,編寫一段簡單的測試代碼如下:

namespace App;

class Test
{
    public static function print ()
    {
        printf("這是一個測試類: %s\n", __CLASS__);
    }
}
 

我們需要在 PHP 腳本的第一行代碼聲明代碼所屬的命名空間(必須是第一行,否則會報錯):

namespace App;
 

表明這段腳本中的所有 PHP 常量、變量、類、函數(shù)都歸屬于這個命名空間,然后我們在這個命名空間中聲明了一個 Test 類,以及一個靜態(tài)方法 print 來打印類名。

接下來,我們在同一目錄下創(chuàng)建一個 App.php 腳本來調(diào)用 Test::print() 方法:

PHP命名空間與類自動加載的實現(xiàn)方法  

App.phpTest.php 歸屬于同一個目錄,所以聲明了相同的命名空間,實際開發(fā)過程中,我們通常就是根據(jù)目錄來組織并管理命名空間的。調(diào)用同一個命名空間中的類和函數(shù),可以像上面代碼這樣直接調(diào)用,如果是不同命名空間的類和函數(shù),則需要通過 use 關(guān)鍵字引入,我們在 ns 目錄下新建一個 testing 子目錄,并在該子目錄下新建一個 Test.php,在這個 PHP 腳本中,我們定義了一個繼承自上級目錄中定義的 Test 父類的同名子類:

PHP命名空間與類自動加載的實現(xiàn)方法  

這里,我們將該子類所屬命名空間聲明為 App\Testing(同一個命名空間下不允許出現(xiàn)重名的類和函數(shù)),然后通過 use 關(guān)鍵字引入上級命名空間中的 Test 類,由于該類名與子類名同名,所以通過 as 關(guān)鍵字為其設(shè)置一個別名 BaseTest,接下來,就可以通過 BaseTest 引用 Test 父類。

Test 子類中,我們重寫了父類 BaseTestprint 方法。

最后,我們可以在 App.php 中這樣調(diào)用這個子類:

namespace App;
use App\Testing\Test as SubTest;

Test::print();
SubTest::print();
 

如果不存在類名沖突,則不需要設(shè)置別名:

namespace App;
use App\Testing\Test;

Test::print();
 

此外,還可以不使用 use 關(guān)鍵字,直接引用包含完整命名空間的類名:

namespace App;

Test::print();
\App\Testing\Test::print();
 

或者這樣,使用部分命名空間:

namespace App;
use App\Testing;

Test::print();
Testing\Test::print();
 

但是,我們這個系列教程約定通過 use 引入完整命名空間,以避免代碼的冗長,提高可讀性。

注:學院君這里只是拋磚引玉,簡單介紹了 PHP 命名空間的基本使用,更多細節(jié)請參考官方文檔 或者現(xiàn)代 PHP 新特性系列(一) —— 命名空間這篇教程(鏈接地址:https://xueyuanjun.com/post/4221)。

 
自動加載命名空間類

當然,現(xiàn)在調(diào)用 php App.php 會報錯,不論是 App\Test 還是 App\Testing\Test 類都提示找不到:

PHP命名空間與類自動加載的實現(xiàn)方法  
-w999
PHP命名空間與類自動加載的實現(xiàn)方法  

要解決這個問題,可以借助上面提到的 spl_autoload_register 函數(shù),將類名所屬命名空間解析為對應(yīng)的目錄路徑(這就是為什么要根據(jù)目錄來組織命名空間),然后把通過 require_once/include_once 引入,我們在 App.php 中加入如下這段代碼:

namespace App;
use App\Testing\Test as SubTest;

spl_autoload_register(function ($className) {
    $path = explode('\\', $className);
    if ($path[0] == 'App') {
        $base = __DIR__;
    }
    $filename = $path[count($path) - 1] . '.php';
    $filepath = $base;
    foreach ($path as $key => $val)
    {
        if ($key == 0 || $key == count($path) - 1) {
            continue;
        }
        $filepath .= DIRECTORY_SEPARATOR . strtolower($val);
    }
    $filepath .= DIRECTORY_SEPARATOR . $filename;
    require_once $filepath;
});

Test::print();
SubTest::print();
 

這樣,我們就可以正常調(diào)用這段代碼了:

PHP命名空間與類自動加載的實現(xiàn)方法  
 

3、通過 Composer 管理命名空間

實際項目開發(fā)時,手動編寫這段 spl_autoload_register 代碼有點麻煩,尤其是項目除了自己編寫的代碼外,還要引入各種第三方庫,我們可以借助 PHP 的包管理工具 Composer 幫我們管理這種命名空間與目錄路徑的映射,在此之前,我們已經(jīng)在 PHP 環(huán)境搭建篇中在本地系統(tǒng)中安裝好了 Composer,因此,只需要在 ns 目錄下運行 composer init 初始化 Composer 設(shè)置即可,按照向?qū)б宦吠伦呒纯?,最后會在項目根目錄下生成一個 composer.json 配置文件:

PHP命名空間與類自動加載的實現(xiàn)方法  

如果項目有第三方庫依賴,可以在 require 中進行配置,這里是一個測試項目,暫時還沒有任何依賴,然后我們在其中配置 autoload 選項來設(shè)置類自動加載機制:

{
    "name": "php/test",
    "description": "A php namespace test project",
    "type": "project",
    "license": "Apache",
    "authors": [
        {
            "name": "xueyuanjun",
            "email": "yaojinbu@outlook.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "classmap": [
            "."
        ]
    }
}
 

這里,我們通過在 classmap 數(shù)組中添加 . 表示當前根目錄作為類自動加載的入口目錄,Composer 會從這里開始讀取所有命名空間并建立目錄映射關(guān)系。接下來執(zhí)行 composer install 初始化依賴庫和類自動加載設(shè)置:

PHP命名空間與類自動加載的實現(xiàn)方法  

初始化過程中,會在根目錄下創(chuàng)建 vendor 用來存放第三方依賴包和類自動加載相關(guān)文件。初始化完成后,可以看到 vendor/composer/autoload_static.php 中已經(jīng)包含了 App 及其子命名空間的目錄映射了:

PHP命名空間與類自動加載的實現(xiàn)方法  

該文件會被 autoload_real.php 引用,autoload_real.php 又會被 vendor/autoload.php 引用:


// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit991075cd5c3b2a6d389bb443802f7669::getLoader();
 

autoload_php 是所有 Composer 管理類自動加載的入口文件,所以我們只需要在代碼中引入這個文件即可通過 Composer 來管理所有類的自動加載,在 App.php 中,修改示例代碼如下:

include_once 'vendor/autoload.php';

use App\Test;
use App\Testing\Test as SubTest;

Test::print();
SubTest::print();
 

比起之前手動編寫 spl_autoload_register 進行類自動加載,現(xiàn)在的代碼更加簡單清晰,執(zhí)行 php App.php,運行結(jié)果如下:

PHP命名空間與類自動加載的實現(xiàn)方法  

感謝各位的閱讀,以上就是“PHP命名空間與類自動加載的實現(xiàn)方法”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對PHP命名空間與類自動加載的實現(xiàn)方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!


本文名稱:PHP命名空間與類自動加載的實現(xiàn)方法
文章源于:http://weahome.cn/article/jhejcc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部