使用自定义异常处理程序创建Laravel 404页面

PHP Exceptions are thrown when an unprecedented event or error occurs. As a rule of thumb, an exception should not be used to control the application logic such as if-statements and should be a subclass of the Exception class.

当发生前所未有的事件或错误时,将引发PHP异常。 根据经验,不应将异常用于控制应用程序逻辑(例如if语句),而应将其作为Exception类的子类。

Being unprecedented, an exception can be thrown at any point or time of our application.

前所未有,可以在我们应用程序的任何时间或任何点抛出异常。

Laravel provides a convenient exception handler class that checks for all exceptions thrown in a laravel application and gives relevant responses. This is made possible by the fact that all Exceptions used in Laravel extend the Exception class.

Laravel提供了一个方便的异常处理程序类,用于检查laravel应用程序中引发的所有异常并给出相关的响应。 由于Laravel中使用的所有Exception都扩展了Exception类,因此可以做到这一点。

One main advantage of having all exceptions caught by a single class is that we are able to create custom exception handlers that return different response messages depending on the exception.

将所有异常捕获到一个类中的一个主要优点是,我们能够创建自定义异常处理程序,该处理程序根据异常返回不同的响应消息。

In this tutorial, we will look at how to create a custom exception handler in Laravel 5.2 and how to return a 404 page depending on the Exception.

在本教程中,我们将研究如何在Laravel 5.2中创建自定义异常处理程序以及如何根据异常返回404页面。

这个怎么运作 ( How it Works )

In Laravel 5.2, all errors and exceptions, both custom and default, are handled by the Handler class in app/Exceptions/Handler.php with the help of two methods.

在Laravel 5.2中,所有错误和异常(无论是自定义还是默认)都由app/Exceptions/Handler.phpHandler类在两个方法的帮助下进行处理。

  • report()

    report()

The report method enables you to log raised exceptions or parse them to error logging engines such as bugsnag or sentry which we will not delve into in this tutorial.

通过report方法,您可以记录引发的异常或将其解析为错误记录引擎,例如bugsnag哨兵 ,我们将不在本教程中深入研究。

  • render()

    render()

The render method responds with an error message raised by an exception. It generates a HTTP response from the exception and sends it back to the browser.

render方法以异常引发的错误消息作为响应。 它根据异常生成HTTP响应,并将其发送回浏览器。

/**
     * 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);
    }

We can however override the default error handling with our own custom exception handler.

但是,我们可以使用我们自己的自定义异常处理程序覆盖默认错误处理。

/**
 * @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);
}

Under the hood, Laravel does it's own handling checks to determine the best possible response for an exception. Taking a look at the parent class (Illuminate\Foundation\Exceptions\Handler), the render method generates a different response depending on the thrown Exception.

在后台,Laravel自己进行处理检查,以确定对异常的最佳可能响应。 看一下父类( Illuminate\Foundation\Exceptions\Handler ),render方法根据抛出的Exception生成不同的响应。

/**
     * 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);
        }
    }

引发Laravel口才异常 ( Throwing a Laravel Eloquent Exception )

In this section, we will create an inbuilt Laravel error by intentionally raising an exception.

在本节中,我们将通过有意引发异常来创建内置的Laravel错误。

To do this, we will try to fetch records that do not exist from a model using the firstOrFail() Eloquent method.

为此,我们将尝试使用firstOrFail()方法从模型中获取不存在的记录。

Go ahead and set up a simple sqlite database. Luckily, Laravel ships with a User model and a corresponding users table. Simply do the following.

继续并建立一个简单的sqlite数据库。 幸运的是,Laravel附带了一个User模型和一个对应的users表。 只需执行以下操作。

  1. Create a new laravel project.

    创建一个新的laravel项目。
  2. Update your .env file to have DB_CONNECTION to be sqlite and the only database parameter.

    更新您的.env文件,使DB_CONNECTION成为sqlite和唯一的数据库参数。
  3. Create a database.sqlite file in the database directory. This is the default sqlite database as configured in config/database.php

    在数据库目录中创建一个database.sqlite文件。 这是在config/database.phpconfig/database.php的默认sqlite config/database.php
  4. Run php artisan migrate on the route of your laravel project. This will set up a users table in the database.

    在您的laravel项目路线上运行php artisan migrate migration。 这将在数​​据库中建立一个用户表。

We will then add a route and a controller to get the first user in our users table who just so happens not to exist.

然后,我们将添加一条路由和一个控制器,以在我们的用户表中获得第一个用户,而该用户恰好不存在。

app/Http/routes.php

app / Http / routes.php

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

App/Http/Controllers/SampleController.php

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

Running this on the browser will return , a ModelNotFoundException error response.

在浏览器上运行此命令将返回,一个ModelNotFoundException错误响应。

NotFoundHttpException

使用自定义处理程序捕获异常 ( Catching Exceptions with a Custom Handler )

ModelNotFoundException (ModelNotFoundException)

With this exception, we can now add a custom handler that returns our own error message.

有了这个例外,我们现在可以添加一个自定义处理程序,该处理程序返回我们自己的错误消息。

We will modify the render method in app/Exceptions/Handler.php to return a json response for an ajax request or a view for a normal request if the exception is one of ModelNotFoundException or NotFoundHttpException.

如果异常是ModelNotFoundExceptionNotFoundHttpException之一,我们将修改app/Exceptions/Handler.phprender方法,以返回ajax请求的json响应或正常请求的视图。

If it is neither of the two, we will let laravel handle the exception.

如果两者都不是,我们将让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);
    }

Add a 404.blade.php file in resources/view/errors to contain our user feedback.

resources / view / errors中添加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>

If we now refresh the page, we have the following message on our view with a 404 status code.

如果现在刷新页面,则视图上将显示以下消息,其中包含404状态代码。

Custom exception handling with 404 status code feedback

NotFoundHttpException (NotFoundHttpException)

When a user visits an undefined route such as /foo/bar/randomstr1ng, a NotFoundHttpException exception, which comes as part of the Symfony package, is thrown.

当用户访问未定义的路由(例如/ foo / bar / randomstr1ng)时 ,将抛出NotFoundHttpException异常,该异常是Symfony软件包的一部分。

To handle this exception, we will add a second condition in the render method we modified earlier and return a message from resources/view/errors/missing.blade.php

为了处理此异常,我们将在先前修改的render方法中添加第二个条件,并从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);
    }

利用Laravel中止方法 ( Taking Advantage of Laravel's Abort Method )

Just like we did in the previous section, Laravel 5.2 makes it all too easy to create custom error pages based on the exception that was thrown.

就像我们在上一节中所做的一样,Laravel 5.2使根据抛出的异常创建自定义错误页面变得非常容易。

We can also simply generate a 404 error page response by calling the abort method which takes an optional response message.

我们还可以通过调用带有可选响应消息的abort方法来简单地生成404错误页面响应。

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

This will check for a corresponding resources/view/errors/404.blade.php and serve a HTTP response with the 404 status code back to the browser. The same applies for 401 and 500 error status codes.

这将检查相应的resources/view/errors/404.blade.php并将带有404状态代码的HTTP响应返回给浏览器。 401和500错误状态代码也是如此。

结论 ( Conclusion )

Depending on an application's environment, you may want to show varying levels of error details. You can set the APP_DEBUG value in config/app.php to either true or false by changing it in your .env file.

根据应用程序的环境,您可能需要显示不同级别的错误详细信息。 您可以通过在.env文件中进行更改,将config/app.phpAPP_DEBUG值设置为true或false。

In most cases, you may not want your users in production to see detailed error messages. It is therefore good practice to set APP_DEBUG value to false while in a production environment.

在大多数情况下,您可能不希望生产环境中的用户看到详细的错误消息。 因此,在生产环境中,最好将APP_DEBUG值设置为false。

翻译自: https://scotch.io/tutorials/creating-a-laravel-404-page-using-custom-exception-handlers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值