【问题标题】:Extending Laravel base controller扩展 Laravel 基本控制器
【发布时间】:2016-11-17 17:46:48
【问题描述】:

我是 Laravel 框架的新手,我想扩展一个基本控制器,然后扩展控制器。但是,我发现当我这样做时,我的控制器不再识别我的会话变量。

这是我的代码

namespace App\Http\Controllers\Settings;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Auth\PermissionController;
use App\Fee;

class FeeController extends PermissionController
{

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        dd(session('userdata')['user_urls']);

        $data['title']="Fees";
        $data['fees']=Fee::all();
        return view('settings.fee.index',$data);
    }

这是我的 PermissionController 代码

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Support\Facades\Gate;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PermissionController extends Controller {

/**
 * Create a new controller instance.
 *
 * @return void
 */
public function __construct(Request $request) {
   if(!session('userdata')['user_urls']->contains($request->path())){
        dd(session('userdata')['user_urls']);
    }
}

}

但我意识到我的session('userdata')['user_urls'] 在 PermissionController 处变为空。但是如果我让 FeeController 扩展 Controller,我的会话变量是完整的。

我需要在权限控制器上使用会话变量进行一些控制。

我在 MAC OSX 和 PHP 7 上运行 Laravel 5.3

【问题讨论】:

  • 尝试从 PermissionController 中删除 __construct。也可以在__construct 方法的末尾尝试使用parent::construct();
  • 您到底想达到什么目的? @Unche
  • @FelippeDuarte,我需要 __construct 方法,以便其他子控制器可以继承 PermissionController 中的功能。然后,当我添加 parent::__construct();我收到以下错误无法调用构造函数
  • @PassionInfinite 在登录时,每个用户都有基于他/她的用户角色允许的 url。这些 url 是会话中的存储。因此,我想从 PermissionController 检查用户尝试访问的 url,并确保它在会话中的 url 中。否则,重定向离开
  • 是的,我知道,这只是为了测试目的。如果我记得的话,会话对象与 Request 对象相结合,这可能会导致您的类/继承出现一些问题。

标签: php laravel session


【解决方案1】:

我已经找到了问题所在。实际上,PermissionController 没有在 Web 中间件组中注册,因此会话不会在 PermissionController 中持久化。因此,您的问题的解决方案就是创建一个名为 Permission 而不是控制器的 trait 并在 FeesContorller 中使用它。

trait Permission{
    public function permission(Request $request) {
        if($request->session()->get('name') != null){
            echo "Hello World";
        }
    }
}

而 FeesController 是这样的:

class FeesController extends Controller
{
    use Permission;

    public function index(Request $request)
    {    
        $this->permission($request); // the method of the trait.
        echo "\n".$request->session()->get('name');
    }
}

输出:

如果在 session 中设置了 name 属性,那么:

Hello World

Passion Infinite

否则

No Output // null

【讨论】:

  • 这是一种智能方法。但是,我希望有比这更无缝的东西。在这里,我仍然需要将 Request 注入到每个必须实现授权的方法中。
【解决方案2】:

我用中间件解决了同样的问题。我创建了一个中间件,它通过检查会话来处理请求的授权,以确保正在访问的控制器操作在会话中可用。

这是中间件

namespace App\Http\Middleware;

use Closure;

class PermissionMiddleware
{
/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    $currentAction = \Route::currentRouteAction();

    list($nothing,$route_action) = explode('App\Http\Controllers\\', $currentAction);

    $user_actions=session('userdata')['user_urls'];

    if((empty($user_actions))||!$user_actions->contains($route_action)){

        return redirect('denied');
    }
    return $next($request);
   }
}

这是控制器

namespace App\Http\Controllers\Settings;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Auth\PermissionController;
use App\Fee;

class FeeController extends Controller
{

/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index(Request $request)
{


    $data['title']="Fees";
    $data['fees']=Fee::all();
    return view('settings.fee.index',$data);
}

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create(Request $request)
{
    $data['title']='New Fee';
    return view('settings.fee.create',$data);
}

因此,我没有使用路由(由于某些其他原因),而是使用了控制器动作。 因此,一旦用户登录,他可以访问的所有控制器操作都会加载到会话中。当他尝试执行任何操作时,中间件会进行检查以确保允许他执行该操作。否则,他会被赶走。

所以,我要么向路由中间件添加“权限”,要么调用

$this-&gt;middleware('permission')

关于控制器的构造方法。

这对我有用。

感谢大家的贡献。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-30
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 2015-01-22
    相关资源
    最近更新 更多