bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

PHP命名空間與類自動加載的實現方法

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

將樂網站建設公司創新互聯公司,將樂網站設計制作,有大型網站制作公司豐富經驗。已為將樂上1000+提供企業網站建設服務。企業網站搭建\成都外貿網站建設要多少錢,請找那個售后服務好的將樂做網站的公司定做!

 

1、從文件引入談起

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

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

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

<?php
require_once 'bootstrap.php';

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

...
 

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

<?php
require_once 'core/Container.php';

...
   
自動加載類文件

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

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

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

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

 

2、命名空間及其使用

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

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

<?php
namespace App;

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

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

namespace App;
 

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

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

PHP命名空間與類自動加載的實現方法  

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

PHP命名空間與類自動加載的實現方法  

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

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

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

<?php
namespace App;
use App\Testing\Test as SubTest;

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

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

<?php
namespace App;
use App\Testing\Test;

Test::print();
 

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

<?php
namespace App;

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

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

<?php
namespace App;
use App\Testing;

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

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

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

 
自動加載命名空間類

當然,現在調用 php App.php 會報錯,不論是 App\Test 還是 App\Testing\Test 類都提示找不到:

PHP命名空間與類自動加載的實現方法  
-w999
PHP命名空間與類自動加載的實現方法  

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

<?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();
 

這樣,我們就可以正常調用這段代碼了:

PHP命名空間與類自動加載的實現方法  
 

3、通過 Composer 管理命名空間

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

PHP命名空間與類自動加載的實現方法  

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

{
    "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 數組中添加 . 表示當前根目錄作為類自動加載的入口目錄,Composer 會從這里開始讀取所有命名空間并建立目錄映射關系。接下來執行 composer install 初始化依賴庫和類自動加載設置:

PHP命名空間與類自動加載的實現方法  

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

PHP命名空間與類自動加載的實現方法  

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

<?php

// autoload.php @generated by Composer

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

return ComposerAutoloaderInit991075cd5c3b2a6d389bb443802f7669::getLoader();
 

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

<?php
include_once 'vendor/autoload.php';

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

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

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

PHP命名空間與類自動加載的實現方法  

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

新聞標題:PHP命名空間與類自動加載的實現方法
網頁地址:http://vcdvsql.cn/article22/jhejcc.html

成都網站建設公司_創新互聯,為您提供響應式網站網站導航企業建站動態網站移動網站建設做網站

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

手機網站建設