如何检查许多控制器方法正在使用的对象的存在DRY和Laravel风格?

时间:2021-03-27 09:22:08

In a Laravel controller I have a couple of methods that all begin by fetching a database record, then after checking if data has been found either continue by rendering a view, or, in case of no data, go to a 404 page.

在Laravel控制器中,我有几种方法都是从获取数据库记录开始,然后在检查数据是否已经找到数据后继续呈现视图,或者,如果没有数据,则转到404页面。

Here's an example:

这是一个例子:

function get_show_user($id)
{
  $user = static::get_user($user_id);
  if (!$user) {
    return Response::error('404', static::$some_common_error404_message);
  }
  return View::make('users.show_readonly_user_data')->with('user', $user);
}

function get_edit_user($id)
{
  $user = static::get_user($user_id);
  if (!$user) {
    return Response::error('404', static::$some_common_error404_message);
  }
  return View::make('users.display_edit_user_form')->with('user', $user);
}

So I'm repeating the entire if (!$user) statement in these methods, even if they all do the same thing.

所以我在这些方法中重复整个if(!$ user)语句,即使它们都做同样的事情。

I'd rather like to do something like this:

我宁愿做这样的事情:

function get_show_user($id)
{
  $user = Users::find($id);
  static::go404_if_null($user);
  return View::make('users.show_readonly_user_data')->with('user', $user);
}

function get_edit_user($id)
{
  $user = Users::find($id);
  static::go404_if_null($user);
  return View::make('users.display_edit_user_form')->with('user', $user);
}

What would be the best way to implement such a DRY feature?

实现这种DRY功能的最佳方法是什么?

Obviously a simple return Response::error('404') would not work in the common existence checker method, since it would only return from that method.

显然,简单的返回Response :: error('404')在公共存在检查器方法中不起作用,因为它只会从该方法返回。

It seems that an Event::fire('404') is not ideal either since it does not terminate the method it has been triggered in.

似乎Event :: fire('404')也不理想,因为它不会终止它被触发的方法。

Perhaps using an exception would be required here, but I'm unsure about this, or how it should be done in Laravel. Where should I catch a 404 Exception of a controller?

也许这里需要使用例外,但我不确定这一点,或者如何在Laravel中完成。我应该在哪里捕获404控制器异常?

1 个解决方案

#1


1  

I think the best way to approach this would be a before filter on your controller.

我认为解决这个问题的最佳方法是在控制器上使用之前的过滤器。

public static $require_user = array(
    'edit_user',
    'show_user',
);

public function before()
{
    $route = Request::route();
    if ( in_array( $route->controller_action, static::$require_user ) )
    {
        $this->user = User::find( $route->parameters[0] );
        if ( is_null($this->user) ) return Response::error('404');
    }
}

Before filters get called after your controller is constructed but before the method is called. If a before filter returns anything other than null, the method is not called and thus execution is stopped.

在构造控制器之后但在调用方法之前调用过滤器之前。如果before过滤器返回除null之外的任何内容,则不调用该方法,因此停止执行。

Here we obtain the current route being executed so we can check which method is going to be called against our array $require_user. This lets us use methods that don't require a user id, such as login.

这里我们获取当前正在执行的路由,这样我们就可以检查要对我们的数组$ require_user调用哪个方法。这使我们可以使用不需要用户ID的方法,例如登录。

Then we retrieve the user instance, getting the id from what would have been passed to the method. You should probably add more error handling here.

然后我们检索用户实例,从传递给方法的内容中获取id。你应该在这里添加更多的错误处理。

Lastly, we check if the user returned was null, meaning not found. If that is the case we return a 404 response, stopping execution of the method.

最后,我们检查用户返回的是否为null,表示未找到。如果是这种情况,我们返回404响应,停止执行该方法。

I hope this helps!

我希望这有帮助!

#1


1  

I think the best way to approach this would be a before filter on your controller.

我认为解决这个问题的最佳方法是在控制器上使用之前的过滤器。

public static $require_user = array(
    'edit_user',
    'show_user',
);

public function before()
{
    $route = Request::route();
    if ( in_array( $route->controller_action, static::$require_user ) )
    {
        $this->user = User::find( $route->parameters[0] );
        if ( is_null($this->user) ) return Response::error('404');
    }
}

Before filters get called after your controller is constructed but before the method is called. If a before filter returns anything other than null, the method is not called and thus execution is stopped.

在构造控制器之后但在调用方法之前调用过滤器之前。如果before过滤器返回除null之外的任何内容,则不调用该方法,因此停止执行。

Here we obtain the current route being executed so we can check which method is going to be called against our array $require_user. This lets us use methods that don't require a user id, such as login.

这里我们获取当前正在执行的路由,这样我们就可以检查要对我们的数组$ require_user调用哪个方法。这使我们可以使用不需要用户ID的方法,例如登录。

Then we retrieve the user instance, getting the id from what would have been passed to the method. You should probably add more error handling here.

然后我们检索用户实例,从传递给方法的内容中获取id。你应该在这里添加更多的错误处理。

Lastly, we check if the user returned was null, meaning not found. If that is the case we return a 404 response, stopping execution of the method.

最后,我们检查用户返回的是否为null,表示未找到。如果是这种情况,我们返回404响应,停止执行该方法。

I hope this helps!

我希望这有帮助!