Laravel/PHP - returning/redirecting from child class

…衆ロ難τιáo~ 提交于 2019-12-10 10:41:28

问题


This is my child controller:

class VolunteersController extends \BaseController
{
    public function index()
    {
        $this->checkForRoles(['admin']);
        //list some secret stuff for admin
    }
}

In my base controller I did this:

class BaseController extends Controller
{
    protected function checkForRoles($roles)
    {
        foreach ($roles as $role) {
            if (!(Auth::user()->hasRole($role))) {
                return Redirect::to('/');
            }
        }
    }
}

Now what I expected was that the line return Redirect::to('/'); in BaseController would redirect the user to home page if his role is not admin.

But it does not happen. //list some secret stuff for admin gets executed in any case.

Edit: Some people may wonder, why am I not using filters. Well yeah, the desired functionality is of filters but apparently filters do not support array arguments in Laravel yet. And as you can see, I need to pass an array of roles to the function.

Please help.


回答1:


The redirect will happen only if VolunteersController::index() will return a "Redirect". It does not do so in your code.

It would, if you had

class VolunteersController extends \BaseController
{
    public function index()
    {
        if ($res = $this->checkForRoles(['admin'])) return $res;
        //list some secret stuff for admin
    }
}



回答2:


I would move the logic to a filter, which will allow the Redirect to function properly. This is the kind of thing filters were designed for.

If you need to pass multiple roles to the filter, instead of passing an array to the filter (which Laravel won't allow), use a delimiter like "+" and then explode the parameter in the filter to simulate passing an array.

For example, your route would be:

Route::get('volunteer', array(
    'before' => 'roles:admin+author', 
    'uses' => 'VolunteersController@index'
));

...and then your filter can easily convert the multiple roles into an array:

Route::filter('roles', function($route, $request, $roles)
{
    $roles = explode('+', $roles);
    // 'admin+author' becomes ['admin', 'author'];
    // continue with your checkForRoles function from above:
    foreach ($roles as $role) {
        if (!(Auth::user()->hasRole($role))) {
            return Redirect::to('/');
        }
    }
}

Then you can remove the logic from the BaseController.

Alternatively, you can pass multiple parameters to a filter as a comma-delimited list. So if you called your route with 'before' => 'roles:admin,author', you could access them in your filter using func_get_args():

Route::filter('roles', function($route, $request, $roles)
{
    $roles = array_slice(func_get_args(), 2); // remove $route and $request
    //...continue as above.


来源:https://stackoverflow.com/questions/26014364/laravel-php-returning-redirecting-from-child-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!