试图获取非对象的属性 - Laravel 5.6

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49899767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 17:39:08  来源:igfitidea点击:

Trying to get property of non-object - Laravel 5.6

phplaravel

提问by LearnLaravel

When I am trying to view a page on my application, I get the error

当我尝试查看应用程序上的页面时,出现错误

Trying to get property of non-object on line 38 on StatController.php

试图在 StatController.php 的第 38 行获取非对象的属性

Researching, this error means trying to get an object or data which doesn't exist.(stand to be correccted).

研究中,此错误意味着尝试获取不存在的对象或数据。(待纠正)。

But my issue is, contact page (to view contacts) doesn't show an error even though contact table is also empty when the application's database is without any data.

但我的问题是,即使当应用程序的数据库没有任何数据时,联系人表也是空的,联系人页面(以查看联系人)也不会显示错误。

What could be causing this error when I try to access the home page when a new user logs in?

当我在新用户登录时尝试访问主页时,可能导致此错误的原因是什么?

StatController

状态控制器

public function home(Request $request) 
{
     $surveys = Survey::where('user_id', Auth::user()->id)->orderBy('created_at','DESC')->first();
     $respondent = Invite::where('user_id', Auth::user()->id)->where('survey_id', $surveys->id)->count();
     $answers = Invite::where('user_id', Auth::user()->id)->where('link_answered', 1)->where('survey_id', $surveys->id)->count();
     $yet_to_respond = Invite::where('user_id', Auth::user()->id)->where('link_clicked', 1)->where('survey_id', $surveys->id)->count();
     $no_response = Invite::where('user_id', Auth::user()->id)->where('link_clicked', 0)->where('survey_id', $surveys->id)->count();

     return view('home', compact('surveys','respondent','yet_to_respond','no_response','answers'));
}

ContactController

联系人控制器

public function index()
{
    $contacts = Contact::where('user_id', Auth::user()->id)->get();
    return view('contact.index',compact('contact'));
}

回答by Luis felipe De jesus Munoz

The problem is that $surveysis coming back null so you must check it before accessing some property:

问题是$surveys返回 null,因此您必须在访问某些属性之前检查它:

public function home(Request $request) 
{
    $respondent = null;
    $answers = null;
    $yet_to_respond = null;
    $no_response = null;

    $surveys = Survey::where('user_id', Auth::user()->id)->orderBy('created_at','DESC')->first();
    if($surveys){
        $respondent = Invite::where('user_id', Auth::user()->id)->where('survey_id', $surveys->id)->count();
        $answers = Invite::where('user_id', Auth::user()->id)->where('link_answered', 1)->where('survey_id', $surveys->id)->count();
        $yet_to_respond = Invite::where('user_id', Auth::user()->id)->where('link_clicked', 1)->where('survey_id', $surveys->id)->count();
        $no_response = Invite::where('user_id', Auth::user()->id)->where('link_clicked', 0)->where('survey_id', $surveys->id)->count();     
    }

    return view('home', compact('surveys','respondent','yet_to_respond','no_response','answers'));
}

Another way is to use optional()method and instead using $surveys->idyou would be using optional($surveys)->id

另一种方法是使用optional()方法,而不是使用$surveys->id您将使用optional($surveys)->id

The optional function accepts any argument and allows you to access properties or call methods on that object. If the given object is null, properties and methods will return null instead of causing an error:

可选函数接受任何参数,并允许您访问该对象的属性或调用该对象的方法。如果给定的对象为 null,则属性和方法将返回 null 而不是导致错误:

回答by Niklesh Raut

As @Luis given you the right answer, This is another way to improve your code, call Inviteone time and then filter out.

正如@Luis 给了您正确的答案,这是改进代码的另一种方法,调用Invite一次然后过滤掉。

public function home(Request $request) 
{
     $surveys = Survey::where('user_id', Auth::user()->id)->orderBy('created_at','DESC')->first();
     $invites = collect([]);
     if($surveys){
        $invites = Invite::where('user_id', \Auth::id())->get();
     }
     $respondent = $invites->where('survey_id', $surveys->id ?? 0)->count();
     $answers = $invites->where('link_answered', 1)->where('survey_id', $surveys->id ?? 0)->count();
     $yet_to_respond = $invites->where('link_clicked', 1)->where('survey_id', $surveys->id ?? 0)->count();
     $no_response = $invites->where('link_clicked', 0)->where('survey_id', $surveys->id ?? 0)->count();
     return view('home', compact('surveys','respondent','yet_to_respond','no_response','answers'));
}

回答by chanafdo

As @Luis mentioned the error is because you are trying to access a property on nullas firstmethod will return nullif no record is found.

正如@Luis 提到的,错误是因为您试图访问一个属性,null因为如果没有找到记录,first方法将返回null

One way is as @Luis mentioned in their answer to check for null or use optionalhelper

一种方法是@Luis 在他们的回答中提到检查 null 或使用optionalhelper

To add to his answer following is on how to achieve the same using Eloquent

添加到他的答案以下是关于如何使用 Eloquent

Using relations

使用关系

In your Surveymodel add the following relations

在您的Survey模型中添加以下关系

public function invitations()
{
    return $this->hasMany(\App\Invite::class);
}

public function responded()
{
    return $this->invitations()
                ->where('link_answered', 1);
}

public function pending()
{
    return $this->invitations()
                ->where('link_clicked', 1);
}

public function unseen()
{
    return $this->invitations()
                ->where('link_clicked', 0);
}

And in your StatController

而在你 StatController

public function home(Request $request) 
{
    $survey = Survey::withCount(['invitations', 'responded', 'pending', 'unseen'])
                    ->where('user_id', Auth::user()->id)
                    ->orderBy('created_at','DESC')
                    ->first();
    return view('home', compact('survey'));
}

Then in your view you can get the count using

然后在您看来,您可以使用

Invitations count: {{ $survey->invitations_count }}
Responded count: {{ $survey->responded_count }}
Pending count: {{ $survey->pending_count }}
Unseen count: {{ $survey->unseen_count }}

Also if your prefer you can clean up your existing code a little bit.

此外,如果您愿意,您可以稍微清理一下现有代码。

public function home(Request $request)
{
    $respondent = 0;
    $answers = 0;
    $yet_to_respond = 0;
    $no_response = 0;

    $survey = Survey::where('user_id', Auth::user()->id)
                    ->orderBy('created_at','DESC')->first();

    if ($survey) {
        $invitationQuery = Invite::where('user_id', Auth::user()->id)
                                 ->where('survey_id', $survey->id);

        $respondent = $invitationQuery->count();
        $answers = with(clone $invitationQuery)->where('link_answered', 1)
                                               ->count();
        $yet_to_respond = with(clone $invitationQuery)->where('link_clicked', 1)
                                                      ->count();
        $no_response = with(clone $invitationQuery)->where('link_clicked', 0)
                                                   ->count();
    }

    return view('home', compact('survey','respondent','yet_to_respond','no_response','answers'));
}