Laravel 5.2 使用自定義異常處理程序創(chuàng)建Laravel 404頁面

當(dāng)PHP發(fā)生意想不到的狀況或者錯(cuò)誤的時(shí)候就會拋出異常。經(jīng)驗(yàn)告訴我們,異常不應(yīng)該用于控制應(yīng)用程序邏輯,例如 if-statements,應(yīng)該是異常類的子類。

我們知道,異??梢栽谖覀兊膽?yīng)用程序的任何時(shí)間點(diǎn)被拋出。Laravel 提供了一個(gè)方便的異常處理程序類,它將檢查在 laravel 應(yīng)用程序中拋出的所有異常并給出相關(guān)的響應(yīng)。Laravel 中使用的所有異常都擴(kuò)展了異常類,使所有異常由單個(gè)類捕獲的一個(gè)主要優(yōu)點(diǎn),我們能夠創(chuàng)建自定義異常處理程序,根據(jù)異常返回不同的響應(yīng)消息。在本教程中,我們將介紹如何在 Laravel 5.2 中創(chuàng)建自定義異常處理程序,以及如何根據(jù)異常返回404頁面。


如何工作

在Laravel 5.2中,所有的異常和錯(cuò)誤不管是自定義的還是默認(rèn)的都是由 app/Exceptions/Handler.php 中的 handle 類處理的,它有兩個(gè)方法:

report()

這個(gè)方法可以記錄引發(fā)的異?;蛘邔⑺鼈兘馕龅藉e(cuò)誤日志引擎(如 bugsnag 或者 sentry),這里不再討論,感興趣的自行研究。

render()

這個(gè)方法將異常引發(fā)的錯(cuò)誤消息生成 HTTP 響應(yīng),并將其發(fā)送給瀏覽器。

/**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $e
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $e)
    {
        return parent::render($request, $e);
    }

我們可以用自己自定義的異常處理程序覆蓋默認(rèn)的錯(cuò)誤處理。

/**
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $e
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $e)
{
    if ($e instanceof CustomException) {
        return response()->view('errors.custom', [], 500);
    }

    return parent::render($request, $e);
}

Laravel 自己會處理處理檢查以確定異常的最佳響應(yīng)??纯锤割?Illuminate\Foundation\Exceptions\Handler, render()根據(jù)拋出的異常生成不同的響應(yīng)。

   /**
     * Render an exception into a response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $e
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function render($request, Exception $e)
    {
        if ($e instanceof HttpResponseException) {
            return $e->getResponse();
        } elseif ($e instanceof ModelNotFoundException) {
            $e = new NotFoundHttpException($e->getMessage(), $e);
        } elseif ($e instanceof AuthenticationException) {
            return $this->unauthenticated($request, $e);
        } elseif ($e instanceof AuthorizationException) {
            $e = new HttpException(403, $e->getMessage());
        } elseif ($e instanceof ValidationException && $e->getResponse()) {
            return $e->getResponse();
        }

        if ($this->isHttpException($e)) {
            return $this->toIlluminateResponse($this->renderHttpException($e), $e);
        } else {
            return $this->toIlluminateResponse($this->convertExceptionToResponse($e), $e);
        }
    }
    

拋出一個(gè) Laravel Eloquent 異常

接下來我們故意創(chuàng)建一個(gè)內(nèi)置的錯(cuò)誤來引發(fā)一個(gè)異常。因此使用 findOrFail() 方法從模型中提取不存在的記錄。
使用 laravel 自帶的 User 模型,執(zhí)行遷移命令創(chuàng)建數(shù)據(jù)表

添加一個(gè)路由和控制器 app/Http/routes.php

Route::get('/user', [
    'uses' => 'SampleController@findUser',
    'as' => 'user'
]);

App/Http/Controllers/SampleController.php

    /**
     * Return the first user in the users table
     *
     * @return Array    User details
     */
    public function findUser()
    {
        $user = User::firstOrFail();
        return $user->toArray();
    }

瀏覽器訪問,一個(gè) ModelNotFoundException 的異常

image
image

捕獲自定義異常

MODELNOTFOUNDEXCEPTION

有了這個(gè)異常,我們現(xiàn)在可以添加一個(gè)自定義處理程序,返回我們自己的錯(cuò)誤消息。

如果異常是 ModelNotFoundExceptionNotFoundHttpException 之一,我們將修改 app/Exceptions/Handler.php中的 render 方法,以返回 ajax 請求的 json 響應(yīng)或正常請求的視圖。如果兩者都不是,就讓 laravel 自己處理異常

/**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $e
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $e)
    {
        //check if exception is an instance of ModelNotFoundException.
        if ($e instanceof ModelNotFoundException) {
            // ajax 404 json feedback
            if ($request->ajax()) {
                return response()->json(['error' => 'Not Found'], 404);
            }

            // normal 404 view page feedback
            return response()->view('errors.missing', [], 404);
        }

        return parent::render($request, $e);
    }

resources/views/errors 中添加一個(gè) 404.blade.php 文件包含反饋信息。

<!DOCTYPE html>
<html>
<head>
    <title>User not found.</title>
</head>
<body>
    <p>You broke the balance of the internet</p>
</body>
</html>

刷新頁面我們可以看到該錯(cuò)誤狀態(tài)消息

image
image

NOTFOUNDHTTPEXCEPTION

當(dāng)用戶訪問未定義的 URL(例如/foo/bar/randomstring),會拋出 NotFoundHttpException 異常。要處理這個(gè)異常, 我們將在我們之前修改的 render 方法中添加第二個(gè)條件,并返回消息到 resources/view/errors/missing.blade.php 視圖中。

/**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $e
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $e)
    {
        //check if exception is an instance of ModelNotFoundException.
        //or NotFoundHttpException
        if ($e instanceof ModelNotFoundException or $e instanceof NotFoundHttpException) {
            // ajax 404 json feedback
            if ($request->ajax()) {
                return response()->json(['error' => 'Not Found'], 404);
            }

            // normal 404 view page feedback
            return response()->view('errors.missing', [], 404);
        }

        return parent::render($request, $e);
    }
    
    /**
     *
     * 對于HttpException 這樣寫,統(tǒng)一性更好
     */
     
      if($this->isHttpException($e))
        {
            if (view()->exists('errors.'.$e->getStatusCode()))
            {
                return response()->view('errors.'.$e->getStatusCode(), [],               $e->getStatusCode());
            }
        }
        return parent::render($request, $e);

使用 Laravel Abort()方法

調(diào)用 abort() 生成404錯(cuò)誤頁面,該方法接收可選的響應(yīng)消息

abort(404, 'The resource you are looking for could not be found');

它將檢查相應(yīng)的 resources/view/errors/404.blade.php 頁面,并將404狀態(tài)碼的 HTTP 響應(yīng)提供給瀏覽器,這同樣適用于401和500錯(cuò)誤狀態(tài)碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 所有示例基于Laravel 5.1.39 (LTS) 今天天氣不錯(cuò),我們來說說表單驗(yàn)證。 Controller中做...
    該葉無法找到閱讀 23,883評論 15 23
  • (轉(zhuǎn)自網(wǎng)絡(luò))畫家小傳 馬蒂斯(1869~1954),西方野獸主義藝術(shù)風(fēng)格的創(chuàng)始人和領(lǐng)導(dǎo)者。出生于法國北部的開始學(xué)畫...
    salen小倫閱讀 525評論 0 2
  • 漫步于幽幽小徑,心中有淡淡愁緒,三兩心事卻無人可訴。只聽得腳底下枯葉沙沙作響。晚霞映照在蒼穹一側(cè),余暉透過錯(cuò)落...
    朝九跡涯閱讀 170評論 0 3
  • 1.HR領(lǐng)域?qū)<?顧問 2.心理咨詢師 3.職業(yè)規(guī)劃師 4.自由撰稿人/簽約作家 5.電臺播音主持 6.育兒達(dá)人/...
    小M的日常閱讀 121評論 0 0

友情鏈接更多精彩內(nèi)容