在這篇博客文章中,我將告訴你關(guān)于 ignition 的一切。
讓我們看看默認(rèn)情況下 php 中有什么。在不使用框架的情況下,PHP 提供了這個(gè)功能。您只會(huì)得到錯(cuò)誤:沒有堆棧跟蹤、沒有請求或應(yīng)用程序詳情。
symfony 的錯(cuò)誤頁面稍微好一些,它向您顯示堆棧跟蹤,但是沒有多大幫助。
下面的截圖是 Whoops,這是 laravel 5 中的標(biāo)準(zhǔn)。它比默認(rèn)的 Symfony 好得多,可以顯示堆棧跟蹤和一些關(guān)于請求的信息。盡管在 Laravel 中 Whoops 是默認(rèn)值,但它是一個(gè)框架無關(guān)的(錯(cuò)誤收集展示)。它僅僅顯示通用信息。
這是 Ignition 的截圖,我們建立的新的錯(cuò)誤視圖。因?yàn)檫@是 Laravel 特有的,我們可以做很多很酷的事情。
發(fā)現(xiàn) Ignition
讓我們來探索 Ignition 所有的細(xì)節(jié)。它是開源的,您可以在這里查看代碼(https://github.com/facade/ignition)。
如果視圖中有錯(cuò)誤,這就是 whoops 顯示它們的方式。注意,異常消息不適合分配的空間。你必須(鼠標(biāo))懸停在它上面才能看完整(信息)。在堆棧跟蹤中,您可以看到使用了編譯后的 Blade 視圖和內(nèi)容。這使得跟蹤哪個(gè) Blade 視圖文件包含錯(cuò)誤變得困難,并且視圖內(nèi)容本身是不可讀的。
Ignition是一個(gè) Laravel 特定的錯(cuò)誤頁面。因此,它可以像鉤子一樣,”掛載”到框架中, 用來顯示未編譯的視圖路徑和您的 Blade 視圖。頂部還有足夠的空間顯示整個(gè)異常頁面,不需要額外的單擊。我們也只在默認(rèn)情況下顯示應(yīng)用程序幀,因?yàn)檫@些可能是您感興趣的幀。
如果您單擊 stack trace 選項(xiàng)卡右側(cè)文件名旁邊的鉛筆圖標(biāo),我們將在您喜歡的編輯器中自動(dòng)打開該文件。默認(rèn)情況下是 phpstorm 。您可以在 ignition 配置文件中將其配置為您最喜歡的編輯器。
注意到右上角的那個(gè)小“望遠(yuǎn)鏡”鏈接了嗎?我們只會(huì)在您安裝了Laravel Telescope(第一方調(diào)試助手)的情況下顯示。如果你點(diǎn)擊那個(gè)鏈接,你將被帶到望遠(yuǎn)鏡內(nèi)發(fā)生錯(cuò)誤的異常。
黑暗模式
如果我們默認(rèn)的錯(cuò)誤屏幕太亮了,你會(huì)很高興知道我們的錯(cuò)誤頁面也有一個(gè)黑暗模式。
Ignition 選項(xiàng)卡
讓我們探索一下 Ignition 頁面上顯示的選項(xiàng)卡。
「請求」選項(xiàng)卡
在「堆棧跟蹤」選項(xiàng)卡旁邊,您將看到「請求」選項(xiàng)卡。它顯示了您對請求的所有預(yù)期信息。
假設(shè)你有一個(gè)路由定義是這樣的::
Route::get('/posts/{post}', function (Post $post) { // });
當(dāng)此路由發(fā)生異常,我們將在 Ignition 中打印 路由參數(shù) post 模型($post 變量),以轉(zhuǎn)化后數(shù)組(toArray?)形式呈現(xiàn)。對于不需要任何綁定的“簡單”路由參數(shù)也是如此。這是一個(gè)很好的方法,可以很容易地看到 Laravel 為這個(gè)特定的路由接收了什么信息。
在路由參數(shù)之后,我們還將向您顯示在此請求中使用的中間件列表。
接下來是“視圖”部分。如果異常發(fā)生在視圖中,我們將在這里顯示視圖名稱。甚至:我們還將給出傳遞給視圖的所有數(shù)據(jù)的列表。
用戶選項(xiàng)卡
“用戶” 選項(xiàng)卡包含有使用應(yīng)用程序的用戶和瀏覽器的更多信息。
上下文選項(xiàng)卡
在 Context ?選項(xiàng)卡中,我們顯示關(guān)于您的 ?repo ?(repo位于何處,簽出提交hash)和環(huán)境(您使用的 PHP 和 Laravel 的哪個(gè)版本)的信息。
調(diào)試選項(xiàng)卡
在 Debug 選項(xiàng)卡中,我們將顯示異常發(fā)生之前發(fā)生的事情。比如查詢、日志和轉(zhuǎn)儲(chǔ)。在轉(zhuǎn)儲(chǔ)旁邊,我們還顯示您將 dump 語句放在何處的文件名。單擊鉛筆圖標(biāo),您就可以直接訪問該文件,并在您最喜歡的編輯器中糾正行號。
建議的解決方案
讓我們來看一下另一個(gè)錯(cuò)誤。這次我們將忘記導(dǎo)入 class。Ignition 報(bào)錯(cuò)頁面是這樣的。
所以,Ignition 在看到異常是關(guān)于一個(gè)沒有找到的 Class 時(shí)。它將嘗試找出在其他命名空間中是否存在這個(gè) Class。如果存在的話,它會(huì)建議我們導(dǎo)入。
Ignition 自帶一系列常見問題的解決方案。若沒有找到Blade視圖,會(huì)采用一個(gè)無效視圖如下所示。
您還可以自定義異常解決方案。需要異常類實(shí)現(xiàn)FacadeIgnitionContractsProvidesSolutions?接口。它要求您添加一個(gè)getSolution 方法。下面是一個(gè)可能的實(shí)現(xiàn)。
namespace AppExceptions; use Exception; use FacadeIgnitionContractsSolution; use FacadeIgnitionContractsBaseSolution; use FacadeIgnitionContractsProvidesSolution; class CustomException extends Exception implements ProvidesSolution { public function getSolution(): Solution { return BaseSolution::create("You're doing it wrong") ->setSolutionDescription('You are obviously doing something wrong. Check your code and try again.') ->setDocumentationLinks([ 'Laracasts' => 'https://laracasts.com', 'Use Flare' => 'https://flareapp.io', ]); } }
下面是在 Ignition 中拋出異常的樣子。
運(yùn)行解決方案
除了僅僅是建議的解決方案,我們也可以運(yùn)行它們。想象一下,例如,您忘記設(shè)置app key。這是用 Ignition 展示錯(cuò)誤的樣子。
如果你點(diǎn)擊“生成app key”按鈕,我們會(huì)在后臺(tái)生成并設(shè)置app key。
刷新頁面后,應(yīng)用程序?qū)⒄9ぷ?除非它含有其他異常)
您可以通過讓異常實(shí)現(xiàn) FacadeIgnitionContractsProvidesSolution 來創(chuàng)建可運(yùn)行的解決方案,這與不可運(yùn)行的解決方案非常相似)。getSolution 方法既可以返回可運(yùn)行的解決方案,也可以返回不可運(yùn)行的解決方案。
namespace AppExceptions; use Exception; use FacadeIgnitionContractsProvidesSolution; class CustomException extends Exception implements ProvidesSolution { public function getSolution(): Solution { return new MyRunnableSolution(); } }
下面是實(shí)現(xiàn)類MyRunnableSolution.示例
namespace AppSolutions; use FacadeIgnitionContractsRunnableSolution; class MyRunnableSolution implements RunnableSolution { public function getSolutionTitle(): string { return 'You are doing it wrong'; } public function getSolutionDescription(): string { return 'You are doing something wrong, but we can fix it for you.'; } public function getDocumentationLinks(): array { return []; } public function getSolutionActionDescription(): string { return 'To fix this issue, all you need to do is press the button below.'; } public function getRunButtonText(): string { return 'Fix this for me'; } public function run(array $parameters = []) { // Your solution implementation } public function getRunParameters(): array { return []; } }
以下是在 Ignition 中 如何拋出自定義異常?CustomException?的樣子.
當(dāng)用戶點(diǎn)擊Fix this for me修復(fù)按鈕時(shí),run 函數(shù)將執(zhí)行。
您可以將參數(shù)從異常發(fā)生的請求傳遞到將運(yùn)行解決方案的請求。讓getRunParameters 返回一個(gè)數(shù)組。該數(shù)組將被傳遞給 run 。
使 Ignition 更聰明
因此,你有能力使用文本或者可運(yùn)行的解決方案來增強(qiáng)自己的異常。 但有時(shí)需要為內(nèi)置的 PHP 異常,甚至是你無法控制代碼的第三方異常提供友好的解決方案。
我們允許你使用 “Solution Providers” 來處理上面提到的難點(diǎn)。 Solution Providers 是可以通過 Ignition 掛鉤到解決方案查找過程的類。 當(dāng)異常被拋出并且 Ignition 接收到異常時(shí),你可以調(diào)用自定義 solution provider 為這個(gè)異常返回一個(gè)或多個(gè)可能的解決方案。
例如,您可以創(chuàng)建一個(gè)自定義“堆棧溢出”解決方案提供程序,它將嘗試為給定的異常找到匹配的堆棧溢出結(jié)果,并將它們作為解決方案返回。
我們也在 Ignition 自身上使用解決方案提供者。下面是這樣一個(gè)解決方案提供者的樣子:
use Throwable; use RuntimeException; use FacadeIgnitionContractsSolution; use FacadeIgnitionSolutionsGenerateAppKeySolution; use FacadeIgnitionContractsHasSolutionForThrowable; class MissingAppKeySolutionProvider implements HasSolutionForThrowable { public function canSolve(Throwable $throwable): bool { if (! $throwable instanceof RuntimeException) { return false; } return $throwable->getMessage() === 'No application encryption key has been specified.'; } public function getSolutions(Throwable $throwable): array { return [ new GenerateAppKeySolution() ]; } }
這些解決方案提供者可以在Ignition中自動(dòng)注冊,如下所示:
namespace AppProviders; use AppSolutionsGenerateAppKeySolution; use FacadeIgnitionContractsSolutionProviderRepository; use IlluminateSupportServiceProvider; class YourServiceProvider extends ServiceProvider { /** * Register services. * * [@return](https://learnku.com/users/31554) void */ public function register(SolutionProviderRepository $solutionProviderRepository) { $solutionProviderRepository->registerSolutionProvider(GenerateAppKeySolution::class); } }
就像這樣,方案提供者將繼續(xù)增強(qiáng) Ignitions 功能,為您的異常提供解決方案,我們迫不及待地想看看社區(qū)將提供什么!
定制 Ignition
Ignition 具有可擴(kuò)展性。您可以添加新選項(xiàng)卡或替換默認(rèn)選項(xiàng)卡。
讓我們看一下提供的?facade/ignition-tinker-tab。 該包是一個(gè)基于?spatie/laravel-web-tinker的包裝器,它允許您在瀏覽器中使用Artisan tinker。
安裝了?facade/ignition-tinker-tab,您就可以在錯(cuò)誤頁面上使用Artisan tinker。
我們還創(chuàng)建了第二個(gè)包, 名為?facade/ignition-code-editor。這個(gè)選項(xiàng)卡替換了默認(rèn)的stack trace選項(xiàng)卡,使用一個(gè)自定義選項(xiàng)卡,允許您在錯(cuò)誤屏幕上編輯代碼。它就在如下操作。
想學(xué)習(xí)如何添加自定義選項(xiàng)卡, 請?jiān)L問?the documentation on adding tabs.
相關(guān)推薦:最新的五個(gè)Laravel視頻教程
原文地址:https://freek.dev/1441-ignition-a-new-Error-page-for-laravel
譯文地址:https://learnku.com/laravel/t/33857