试图获取非对象的属性 - 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
Trying to get property of non-object - Laravel 5.6
提问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 $surveys
is 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->id
you 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 Invite
one 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 null
as first
method will return null
if no record is found.
正如@Luis 提到的,错误是因为您试图访问一个属性,null
因为如果没有找到记录,first
方法将返回null
。
One way is as @Luis mentioned in their answer to check for null or use optional
helper
一种方法是@Luis 在他们的回答中提到检查 null 或使用optional
helper
To add to his answer following is on how to achieve the same using Eloquent
添加到他的答案以下是关于如何使用 Eloquent
Using relations
使用关系
In your Survey
model 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'));
}