摘要:異常處理上節解讀源碼一自動加載看完了自動加載部分,根據代碼執行順序,的行注冊錯誤和異常處理機制加載慣例配置文件下面的加載配置文件不用說,現在重點看一下異常處理。博客鏈接解讀源碼二異常處理和請求生命周期
異常處理
上節解讀 thinkphp5 源碼(一):自動加載看完了自動加載部分,根據代碼執行順序,base.php的59-64行
// 注冊錯誤和異常處理機制 hinkError::register(); // 加載慣例配置文件 hinkConfig::set(include THINK_PATH . "convention" . EXT);
下面的加載配置文件不用說,現在重點看一下異常處理。
打開library/think/Error.php,register函數。
public static function register(){ error_reporting(E_ALL); set_error_handler([__CLASS__, "appError"]); set_exception_handler([__CLASS__, "appException"]); register_shutdown_function([__CLASS__, "appShutdown"]); }
通過error_reporting()來這是php的報錯級別。E_ALL為顯示所有報錯信息,所以在運行時NOTICE級別的警告也會顯示,如果不想顯示NOTICE信息,可以在項目common文件中重新設置一下報錯級別:error_reporting(E_ALL ^ E_NOTICE);
set_error_handler指定appError來處理系統異常
set_exception_handler來指定appException來處理用戶拋出的異常
register_shutdown_function來指定appShutdown處理超時異常
然后使用getExceptionHandler方法來獲取異常處理對象的實例。
public static function getExceptionHandler() { static $handle; if (!$handle) { // 異常處理handle $class = Config::get("exception_handle"); if ($class && class_exists($class) && is_subclass_of($class, " hinkexceptionHandle")) { $handle = new $class; } else { $handle = new Handle; } } return $handle; }
里面有一句$class = Config::get("exception_handle");也就是說我們可以通過修改配置參數來指定新的異常處理對象。
library/think/exception/ 下是幾個異常處理類,主要就是在開啟debug的情況下輸出異常等級,異常信息,異常代碼等等。然后也對CLI模式下做了異常輸出的處理。
請求生命周期 應用初始化base.php看完之后,基本上框架的初始化工作也做完了。然后回到,start.php中。
// 執行應用 App::run()->send();
這里是一個連貫操作,我們需要先看一下App::run()返回的是什么對象
library/think/App.php,run方法
run方法可以接收一個Request對象,如果不存在,則獲取該對象。
is_null($request) && $request = Request::instance();
然后通過$config = self::initCommon();來初始化應用
看initCommon()中的代碼可以發現主要做了以下幾件事情。
首先通過init()方法來初始化應用,主要就是加載該模塊或者應用運行所需的文件,配置、common文件、語言包
然后判斷如果配置中關閉debug的話則通過ini_set("display_errors", "Off");來關閉異常信息的顯示。
ini_set("display_errors", "Off")和error_reporting(0)的區別主要在于,用前者設置后頁面不顯示異常信息,但是可以通過日志來收集異常信息,主要用在生產環境。而error_reporting(0);則屏蔽了所有異常信息,這種做法肯定是不太科學的。
然后判斷如果不是cli模式下則重新申請一個緩沖區。使用緩沖區的作用主要是兩方面,一是可以在輸出一些內容之后在設置header(例如cookie等),使得程序設計的邏輯性變得簡單;二是可以對緩沖區里面的輸出內容撤銷、刪除、壓縮、保存到文件等操作。
這里通過ob_get_level來判斷緩沖區是否為空,來處理緩沖區的歷史內容。
然后注冊命名空間、加載額外文件、設置時區、注冊app_init的hook。
回到run方法
if (defined("BIND_MODULE")) { // 模塊/控制器綁定 BIND_MODULE && Route::bind(BIND_MODULE); } elseif ($config["auto_bind_module"]) { // 入口自動綁定 $name = pathinfo($request->baseFile(), PATHINFO_FILENAME); if ($name && "index" != $name && is_dir(APP_PATH . $name)) { Route::bind($name); } }
BIND_MODULE主要是來處理默認模塊的,tp5的路由規則是/m/c/a,如果應用只有一個模塊,則可以用過設置BIND_MODULE常量來設置模塊名稱。
通過配置auto_bind_module參數也可以設定模塊名稱。
$request->filter($config["default_filter"]);注入過濾方法
開啟多語言支持。
路由檢測// 獲取應用調度信息 $dispatch = self::$dispatch; if (empty($dispatch)) { // 進行URL路由檢測 $dispatch = self::routeCheck($request, $config); } // 記錄當前調度信息 $request->dispatch($dispatch); // 記錄路由和請求信息 if (self::$debug) { Log::record("[ ROUTE ] " . var_export($dispatch, true), "info"); Log::record("[ HEADER ] " . var_export($request->header(), true), "info"); Log::record("[ PARAM ] " . var_export($request->param(), true), "info"); }
主要通過self::routeCheck($request, $config);來對路由進行分類,然后進行相應的操作(等后面進詳細閱讀)。主要有以下幾種類別
路由到模塊/控制器/操作; 路由到外部重定向地址; 路由到控制器方法; 路由到閉包函數; 路由到類的方法;路由分發
根據上面得到分類,進行相應的操作,得到返回的數據(等后面進詳細閱讀)。
請求響應主要通過Response類來進行響應。
注冊app_end的hook,并返回response對象。
所以前面App::run()事實上得到的是一個經過一系列操作之后的response對象然后執行response->send();
拿到緩沖區中的數據,并輸出,至此,結束請求。
博客鏈接:解讀 thinkphp5 源碼(二):異常處理和請求生命周期
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30495.html
摘要:索性讀一下它的源碼。行載入類載入類,這個類比較重要,實現了自動加載。注冊錯誤和異常處理機制加載慣例配置文件接下來我們看一下自動加載的實現方法。所以借助此函數可以達到自動加載。博客鏈接解讀源碼一自動加載 聽說 TP5 已經 RC4 了,曾經在 RC3 的時候用它寫過一個小東西。官方說從 RC4 以后改動不是太大。索性讀一下它的源碼。然后順便記錄一下,如有錯漏,請路過大神多多指正! 入口 ...
摘要:如果遍歷后沒有找到,則加載失敗。在之后碰到了之后直接拿來用,提高系統自動加載的性能。這里我們就講完了注冊自動加載。使用自動加載我們在中定義了我們自動加載函數式方法。 繼 生命周期的第二篇,大家盡可放心,不會隨便鴿文章的 第一篇中,我們提到了入口腳本,也說了,里面注冊了自動加載的功能 本文默認你有自動加載和命名空間的基礎。如果沒有請 看此篇文章 php 類的自動加載與命名空間 自動加載...
摘要:本文源碼為版本。的代碼結構也是一個很經典的定義結構構造函數實例修改函數原型共享實例方法,它提供事件通道上事件的訂閱撤消訂閱調用。 前言 cordova(PhoneGap) 是一個優秀的經典的中間件框架,網上對其源代碼解讀的文章確實不多,本系列文章試著解讀一下,以便對cordova 框架的原理理解得更深入。本文源碼為cordova android版本6.1.2。 源碼結構 我們使用IDE...
摘要:第一篇文章我會結合和的部分源碼,來說明注入生命周期的過程。說到源碼,其實沒有想象的那么難。但是源碼的調用樹會復雜很多。應用的業務代碼逐漸復雜,事件事件總線等通信的方式的弊端就會愈發明顯。狀態管理是組件解耦的重要手段。前言 這篇文章是【前端詞典】系列文章的第 13 篇文章,接下的 9 篇我會圍繞著 Vue 展開,希望這 9 篇文章可以使大家加深對 Vue 的了解。當然這些文章的前提是默認你對 ...
閱讀 775·2023-04-25 16:55
閱讀 2806·2021-10-11 10:59
閱讀 2070·2021-09-09 11:38
閱讀 1782·2021-09-03 10:40
閱讀 1485·2019-08-30 15:52
閱讀 1125·2019-08-30 15:52
閱讀 954·2019-08-29 15:33
閱讀 3494·2019-08-29 11:26