亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > PHP > 正文

PHP自動加載機制實例詳解

2024-05-05 00:04:25
字體:
來源:轉載
供稿:網友

本文實例講述了PHP自動加載機制。分享給大家供大家參考,具體如下:

在php中,我們一般使用 requirerequre_onceincludeinclude_once 這四個命令來加載其他php文件,這在一般小型的php文件中是沒有任何問題的,相信每個初學者都會遇到這樣的應用場景:使用一個 Db.php 來定義數據庫連接,在其他文件中直接引用這個文件,達到代碼復用的效果。

再讓我們考慮這樣一個應用場景,如果我們使用一個框架,或者一個第三方包,里面一般有成百上千個類文件,而我們通常是不用自己去加載這些文件的,此時用的便是php的自動加載機制。

定義一種自動加載模式

在傳統的應用中,通常自定義 __autoload()。如下

define("DIR", "/var/www/myWeb/myClass/");function __autoload($classname) {  require DIR.$classname.'.class.php';}$book = new Book();

上述代碼運作過程如下:

1. 自定義 __autoload 函數,它定義了類文件的加載方式
2. 當我們 new 一個 Book 實例時,它首先看當前是否包含了這個類,如果不存在則自動調用 __autoload 函數并將類名 Book 作為參數傳遞給這個函數。這實際上就是一種動態加載的方式,只有我們需要的類文件才會被加載。
3. 找到 __autoload 函數后,發現定義好的加載動作 require DIR.$classname.'.class.php'; 這時候它就會去 DIR 目錄下查找 Book.class.php 文件,如果存在這個文件則加載。
4. 關于類 Book.class.php 的定義必須滿足如下條件:類名和文件名一致;一個文件只定義一個類。

Book.class.php 文件如下

class Book {  public function __construct() {    echo "this is Book's construct/n";  }}

注冊多種加載模式

對于我們自己的簡單應用,一種加載模式可能夠用了,但是對于較大型的應用,上面的方式存在明顯的缺陷:__autoload函數不能重復定義,也就是說我們只能定義一種加載文件的模式,最終的結果就是我們的類只能放在一個地方,這顯然是不符合實際要求的。因此php使用了函數 spl_autoload_register 來代替 __autolaod。

代碼如下:

define("MODEL_DIR", "/var/www/myWeb/myModel/");define("CONTROLLER_DIR", "/var/www/myWeb/myController/");// 定義Model類加載方式function loadModel($classname) {  $filename = MODEL_DIR.$classname.'.php';  if (file_exists($filename))    require $filename;}// 定義Controller加載方式function loadController($classname) {  $filename = CONTROLLER_DIR.$classname.'.php';  if (file_exists($filename))    require $filename;}// 注冊兩個加載函數spl_autoload_register("loadModel");spl_autoload_register("loadController");// 自動加載類文件$bookMode = new BookMode();$bookController = new BookController();

在上面的代碼中,我們可以看到:

1. 可以使用任意函數名定義多個加載函數
2. 在 spl_autoload_register 對加載函數進行注冊,實際上應該是添加到一個類似雙向隊列的數據結構中。
3. 當我們 new 的對象不存在于當前文件時,它會自動從我們的加載函數中查找,并且是按照我們使用 spl_autoload_register 注冊的順序進行的。
4. 需要注意的是,此時如果我們定義了 __autoload 方法,也必須進行注冊,否則會被忽略。

spl_autoload_register三種注冊函數的方式:

spl_autoload_register(funName); // 直接注冊一個普通加載函數spl_autoload_register(obj::method); // 注冊一個靜態加載方法spl_autoload_regitser(array(obj, method)); // 當obj為類字符串時,只能加載靜態方法。否則都可以。

實例

在各種php框架中,也大量用到了自動加載機制,我們通過laravel的一個小例子來看下。

laravel通過 Ioc 容器幫我們管理依賴,讓我們可以通過函數參數的方式愉快地獲得了類實例,但我們也發現,我們并沒有require文件,那容器又是如何找到我們的文件地址的?下面我們就來解決這個問題。

通過入口文件 index.php 我們一步步搜索,可以找到 /vendor/composer/ClassLoader.php 文件。

部分代碼如下

public static function loadClassLoader($class){  if ('Composer/Autoload/ClassLoader' === $class) {    require __DIR__ . '/ClassLoader.php';  }}public static function getLoader(){  if (null !== self::$loader) {    return self::$loader;  }  spl_autoload_register(array('obj', 'loadClassLoader'), true, true);  // 通過命名空間的方式使用注冊的加載類  self::$loader = $loader = new /Composer/Autoload/ClassLoader();  spl_autoload_unregister(array('obj', 'loadClassLoader'));  if (PHP_VERSION_ID >= 50600) {    // 該文件定義了包類和用戶類的命名空間和實體文件的映射    // 以及其他一些東西    require_once __DIR__ . '/autoload_static.php';    // 初始化$loader一些屬性。    // 我們關注autoload_static.php文件的類映射    // 被賦值在了 $loader的$classMap屬性        call_user_func(/Composer/Autoload/ComposerStaticInit::getInitializer($loader));    // ...  }  // ...  $loader->register(true);  // ...  return $loader;}

它調用了 getLoader() 函數,并將 loadClassLoader 函數注冊到加載函數注冊隊列。然后就可以通過命名空間的方式 self::$loader = $loader = new /Composer/Autoload/ClassLoader(); 實例化 ClassLoader 類。

緊接著,他載入了 /autoload_static.php 文件,大致內容如下

// 里面還定義了包類和psr的一些標準public static $classMap = array (  'App//Common//Collection' => __DIR__ . '/../..' . '/app/Common/Collection.php',  'App//Common//MgDB' => __DIR__ . '/../..' . '/app/Common/MgDB.php',  'App//Common//Redis' => __DIR__ . '/../..' . '/app/Common/Redis.php',)

看到這里筆者興奮了,因為上面的 Collection, Redis 正是筆者定義的類!
然后就是我們在laravel經常聽到的一個名詞 “register”。查看 ClassLoader 類的 register 方法如下:

public function register($prepend = false){  spl_autoload_register(array($this, 'loadClass'), true, $prepend);}public function loadClass($class){  if ($file = $this->findFile($class)) {    includeFile($file);    return true;  }}public function findFile($class){  // ...  // class map lookup  if (isset($this->classMap[$class])) {    return $this->classMap[$class];  }  // ...}

上面的register方法同樣使用了自動加載機制。并將通過findFile函數和$classMap數組直接找到對應的類的具體位置。這也就是我們不用自己去加載類文件的原因 – 當我們實例化一個代碼中找不到的類時,它便會在這里加載對應的類。

看到這里我們也發現了它的使用和我們之前講的并不完全一致,我們是注冊函數是為了通過文件夾來尋找類,而laravel注冊函數是為了注冊一個映射數組然后直接調用(整了個映射文件三千多行。。。)具體為什么要這么做得等下次通讀加載源碼部分后再寫一篇博文(本來只想找一個框架的例子,蜜汁尷尬)

筆者實例

兩年前負責學校某個協會線上部分時,主要是做微信開發,因為時不時就要加一個新功能,所以如果用一般的方式寫起來是比較痛苦的,但是用框架又有點大材小用。因為就使用了下面這種簡單的方式:

require "./basic/init.php";define('WEB_PATH', '');//聲明自動加載函數并注冊,指示加載路徑與加載方法  function wechatAutoload($class_name)  {    $file_road = './function/'.$class_name.'.class.php';    if(file_exists($file_road))    {      require_once($file_road);    }  }  spl_autoload_register('wechatAutoload');//----------------------------------------------

初始化好配置之后,我們注冊了一個加載函數,以后每一個新功能都只要在 function 文件夾下新增一個文件即可,其他部分的改動很少或者根本不用(根據業務場景)。

參考:PHP: spl_autoload_register - Manual

希望本文所述對大家PHP程序設計有所幫助。


注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人jvid在线播放| 久久综合国产精品台湾中文娱乐网| 一区二区日韩精品| 91a在线视频| 欧美在线欧美在线| 亚洲欧美第一页| 亚洲视频电影图片偷拍一区| 欧美视频在线观看免费网址| 欧美成人免费va影院高清| 久久97久久97精品免视看| 成人激情视频在线播放| 欧美成人精品一区二区三区| 欧美国产极速在线| 亚洲热线99精品视频| 国产最新精品视频| 亚洲国产一区二区三区四区| 日韩一区二区三区国产| 日韩动漫免费观看电视剧高清| 国产乱人伦真实精品视频| 欧美一级免费看| 国产精品免费一区二区三区都可以| 91久久精品国产91久久| 日韩精品福利在线| 日韩欧美在线视频| 欧美日韩亚洲网| 久久久国产影院| 国产在线播放91| 欧美性猛交xxxx乱大交3| 欧美日韩在线免费| 欧美成人免费va影院高清| 日韩欧美在线字幕| 青青a在线精品免费观看| 亚洲品质视频自拍网| 精品免费在线观看| 在线性视频日韩欧美| xvideos成人免费中文版| 国产精品夜间视频香蕉| 在线观看欧美成人| 久久激情视频免费观看| 久久精品人人爽| 亚洲无限av看| 久久精品91久久香蕉加勒比| 国内精久久久久久久久久人| 欧洲午夜精品久久久| 成人网在线免费看| 亚洲精品456在线播放狼人| 久久久久久久久国产精品| 国产精品h在线观看| 久久久久久久久久av| 欧美日本啪啪无遮挡网站| 亚洲女人被黑人巨大进入| 操91在线视频| 国产精品69精品一区二区三区| 亚洲精品永久免费精品| 亚洲国产精品va在看黑人| 国内久久久精品| 欧美成人午夜激情| 97在线看福利| 国产精品成久久久久三级| x99av成人免费| 91九色精品视频| 日韩大片在线观看视频| 亚洲人午夜色婷婷| 欧美性xxxxhd| 亚洲国产福利在线| 奇米4444一区二区三区| 国产精品久久久久av免费| 日韩av男人的天堂| 国产精品免费观看在线| 91成人免费观看网站| 久久久精品免费| 成人国产亚洲精品a区天堂华泰| 91九色单男在线观看| 欧美乱大交xxxxx另类电影| 日韩国产欧美精品一区二区三区| 欧美成人精品不卡视频在线观看| 日产精品99久久久久久| 久久久噜噜噜久久中文字免| 欧美尤物巨大精品爽| 欧美日韩不卡合集视频| 亚洲精品久久久久久久久久久久| 高清视频欧美一级| 大伊人狠狠躁夜夜躁av一区| 日韩中文字幕国产| 美乳少妇欧美精品| 国产精品美乳一区二区免费| 欧美日韩一区二区免费在线观看| 日韩网站免费观看高清| 岛国视频午夜一区免费在线观看| 亚洲免费高清视频| 久久成人在线视频| 欧美亚洲视频一区二区| 日本三级韩国三级久久| 欧美体内谢she精2性欧美| 岛国视频午夜一区免费在线观看| 日韩在线免费观看视频| 国产日韩欧美在线视频观看| 日韩在线观看免费高清完整版| 韩国国内大量揄拍精品视频| 亚洲欧美中文日韩v在线观看| 中文字幕精品www乱入免费视频| 国产91精品高潮白浆喷水| 在线激情影院一区| 色偷偷9999www| 欧美午夜影院在线视频| 九九热在线精品视频| 亚洲一区二区三区视频播放| 欧美色视频日本高清在线观看| 亚洲区bt下载| www.久久久久| 亚洲xxxx视频| 国产区精品视频| 亚洲图片欧洲图片av| 久久久在线视频| 日韩美女av在线| 久久久国产视频91| 亚洲性生活视频在线观看| 日韩精品中文字幕有码专区| 久久久久中文字幕| 国产精品成人观看视频国产奇米| 国产精品video| 国产精品久久久久秋霞鲁丝| 97在线视频精品| 911国产网站尤物在线观看| www亚洲欧美| 国产亚洲精品日韩| 欧美日本在线视频中文字字幕| 欧美一级大片视频| 精品女同一区二区三区在线播放| 亚洲精品白浆高清久久久久久| 国产精品中文字幕在线| 成人天堂噜噜噜| 欧美在线视频免费播放| 国产精品99蜜臀久久不卡二区| 国产亚洲欧美日韩精品| 麻豆精品精华液| 久久久91精品| 国产中文字幕日韩| 久久99精品久久久久久青青91| 91久热免费在线视频| 中文字幕欧美精品日韩中文字幕| 国产97在线播放| 51ⅴ精品国产91久久久久久| 欧美大全免费观看电视剧大泉洋| 亚洲欧美日韩一区二区三区在线| 久久精品中文字幕一区| 91精品国产色综合久久不卡98| 午夜精品久久久久久久男人的天堂| 黑人巨大精品欧美一区二区三区| 日韩理论片久久| 日韩精品视频免费在线观看| 91久久在线视频| 亚洲一区二区中文字幕| 国产999视频| 亚洲精品一区二区在线| 一区二区三区视频观看| 成人欧美一区二区三区黑人孕妇| 国产精品日韩欧美大师| 成人羞羞国产免费| 日韩精品在线电影| 日韩免费电影在线观看| 亚洲欧美中文日韩在线v日本| 亚洲国语精品自产拍在线观看| 91精品国产色综合|