【问题标题】:Laravel 5 Auth is non object in Controller constructLaravel 5 Auth 是 Controller 构造中的非对象
【发布时间】:2017-10-18 18:21:25
【问题描述】:

app\Http\Controller 中有一个名为Controller 的主控制器类,所有其他控制器都继承它。在任何其他控制器中,以下代码都可以正常工作:

class OtherController extends Controller{

   public function index(){
      dd(\Auth::user()->id);
   }
} 

但是,在Controller.php 即父类中,当我尝试在construct 方法中执行类似操作时,我遇到了尝试获取非对象的属性 错误:

class Controller extends BaseController {

    use AuthorizesRequests,
        DispatchesJobs,
        ValidatesRequests;
    public $foo = 'null';

    public function __construct() {
        $this->middleware('auth');
        dd(\Auth::user()->id);//Error is here.
        dd(\Route::getCurrentRoute()->action['controller']);

    }

}

我该如何解决这个问题?

【问题讨论】:

    标签: php laravel-5 laravel-5.4


    【解决方案1】:

    编辑以添加实际答案

    尝试在parent::call_action() 行之前声明此方法并将您的代码放入其中:

    public function callAction($method, $parameters)
    {
        // Put your code right here
    
        // then do this last
        return parent::callAction($method, $parameters);
    }
    

    取自this 页面底部。简而言之,callAction 总是在目标方法被调用之前被调用,但它也在中间件运行之后 被调用,因此您将能够正确访问您的 auth 外观。您在构造函数中尝试执行的任何操作都很可能在此方法中按您希望的方式工作。

    原答案

    自从我在 laravel 5.4 中闲逛以来已经有一段时间了,但是如果我没记错的话,中间件直到控制器构造函数之后才会触发,这意味着您特别 不能 这样做你想做什么。 auth 中间件不会使用登录用户填充 Auth 外观,直到构造控制器之后,但在调用控制器方法之前(这就是您的第一个示例有效的原因)。

    我相信这是预期的行为,因此不太可能改变。

    简而言之(除非有更多知识渊博的人纠正我)你必须找到另一种方法来做你想做的任何事情。

    编辑以添加

    确实,this question 清楚地表明我的怀疑是正确的。中间件在控制器构造函数之后触发,这意味着您无法访问控制器构造函数内的登录用户。回想起来,这显然是这种情况,因为您可以在控制器构造函数中做的一件事是指定系统应该运行哪些中间件。如果中间件已经运行,那么您将无法执行此操作。所以它的缺点是你不能(实际上)从控制器构造函数中访问 Auth 门面。这是 laravel 团队有意为之,因此不会很快改变。你将不得不找到另一种方法来做到这一点。

    【讨论】:

    • 确实,我需要实现的是beforeActionCakePHP 中的回调。即在执行任何控制器操作之前执行特定任务。
    • 更多关于你正在尝试做的事情的细节可能有助于找出正确的解决方案
    • 这正是我所需要的。事实上,我打算制作自己的授权实现,因此在Controller.php 中使用这种方法对于这种方法至关重要。
    【解决方案2】:

    我已经根据您的错误更新了我的答案...确保在文件顶部添加use Illuminate\Support\Facades\Auth;

    现在使用 laravel 4.2+ 很容易获取用户的 id:

    $userId = Auth::id();
    

    仅此而已。

    但要检索除 id 以外的用户数据,您可以使用:

    $email = Auth::user()->email;
    

    更多详情请查看security part of the documentation

    【讨论】:

    • 我收到了这个错误:App\Http\Controllers\Controller cannot use Illuminate\Support\Facades\Auth - it is not a trait
    • 你不想做这两件事。在 PHP 中有两个地方可以放置 use 指令:在文件的顶部(在命名空间之后但在类定义之前)或在类的顶部。类顶部的 'use' 指令告诉 PHP 你想使用一个 trait。 auth 外观不是特征,因此(正如您所发现的)如果您尝试将其用作特征,则会收到错误。如果您在文件顶部放置一个“使用”指令,它基本上只会在 PHP 中为您的类设置别名。但是,这不是您的问题(稍后会详细介绍)
    • use Illuminate\Support\Facades\Auth 放在文件顶部实际上并没有改变任何东西,因为您对 Auth 类的引用只是 Illuminate\Support\Facades\Auth 的简写。所以 '\Auth::user()` 与use Illuminate\Support\Facades\Auth 后跟Auth::user() 执行相同的操作,这也相当于use Auth 后跟Auth::user()。在所有情况下,您都在导入同一个类,因此更改它不会解决任何问题。
    • Laravel 4.2 中的示例不相关,我担心,因为据我所知,在构造函数 did 中引用 Auth 在 laravel 的早期版本中有效。我相信在 laravel 5.3 中已经取消了对此的支持。
    • 使用认证;在控制器顶部
    猜你喜欢
    • 2018-03-09
    • 2015-09-08
    • 1970-01-01
    • 2017-09-14
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多