长期的Google员工,这里的第一次提问者。嗨伙计。 从Laravel 5.1.10到5.6更新后,我正在调试和更新我的应用程序 这个bug很难谷歌。
探索我的错误消息“试图获取非对象的属性”我认为发生的事情是,过去工作得很好的嵌套关系路径给我的对象,现在改为给我一个属性数组
下面有更多代码,但这是我视图中的代码段:
@section('content')
<h2>
<?php // Header: project number and title ?>
@if ($bookingDefault->project->courseNumber)
{{ $bookingDefault->project->courseNumber }}:
@endif
这会导致错误:
Trying to get property 'courseNumber' of non-object
它没有返回null;数据就在那里,如果我以一个数组的形式访问项目,它就可以正常工作:
@section('content')
<h2>
<?php // Header: project number and title ?>
@if ($bookingDefault->project['courseNumber'])
{{ $bookingDefault->project['courseNumber'] }}:
@endif
所以我知道关系定义得好,因为它正在寻找项目。它不再给视图提供适当的对象了。 我可以改变大量的视图来代替作为数组访问属性,但这需要很多代码来梳理和更改,并且不允许我访问对象的方法。我宁愿修复为什么我得到一个数组而不是我以前得到的对象。
可能相关的代码:
来自app / Http / Kernel.php(部分) - 我检查了SubstituteBindings :: class是否存在。
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
来自routes / web.php(部分)的- 所有旧的Route :: model和Route :: bind仍然存在。我不确定我是应该将它们拿出来还是把它们放在其他地方,但摆弄它并没有改变任何东西。我尝试将它们移动到RouteServiceProvider的boot()函数,但这并没有改变任何东西,所以我把它们放回web.php。
Route::model('bookingdefaults', 'BookingDefault');
Route::model('bookings', 'Booking');
Route::model('people', 'User');
Route::model('projects', 'Project');
Route::bind('bookingdefaults', function($value, $route) {return App\BookingDefault::where('id', $value)->first();});
Route::bind('bookings', function($value, $route) {return App\Booking::where('id', $value)->first();});
Route::bind('people', function($value, $route) {return App\User::where('id', $value)->first();});
Route::bind('projects', function($value, $route) {return App\Project::where('id', $value)->first();});
在模型中 - 再次,不是完整的代码:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BookingDefault extends Model
{
protected $guarded = [];
// RELATIONSHIPS
// always belongs to a certain project
public function project()
{
return $this->belongsTo('App\Project');
}
// always happens a certain place
public function location()
{
return $this->belongsTo('App\Location');
}
// many bookings could be made from this default
public function bookings()
{
return $this->hasMany('App\Booking');
}
// each booking default will suggest several roles that might be filled in a booking
public function bookingDefaultRoleAssignments()
{
return $this->hasMany('App\BookingDefaultRoleAssignment');
}
// somtimes it is defining a default of a certain type, but if this is a
// customized default then it may not belong to a bookingType
public function bookingType()
{
return $this->belongsTo('App\BookingType');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Mail;
use App\Booking;
class Project extends Model
{
protected $guarded = [];
// RELATIONSHIPS
public function bookings()
{
return $this->hasMany('App\Booking');
}
// a project can have defaults for several types of booking
public function bookingDefaults()
{
return $this->hasMany('App\BookingDefault');
}
// there will be many assignments of users to this project in various roles
public function projectRoleAssignments()
{
return $this->hasMany('App\ProjectRoleAssignment');
}
public function projectType()
{
return $this->belongsTo('App\ProjectType');
}
}
来自BookingDefaultsController.php的(部分 - 实际控制器超过1000行)
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\Collection;
use App\User;
use App\Booking;
use App\BookingDefault;
use App\BookingDefaultRoleAssignment;
use App\BookingRoleAssignment;
use App\BookingRole;
use App\BookingType;
use App\Location;
use App\Project;
use App\Qualification;
use Illuminate\Support\Facades\DB;
use Input;
use Redirect;
use Mail;
class BookingDefaultsController extends Controller
{
/**
* Show the form for editing the specified resource.
*/
public function edit(BookingDefault $bookingDefault)
{
// We'll need all the options for form dropdowns
$locations = Location::where('status', 'active')->orderby('location_name')->get();
$bookingTypes = BookingType::all();
$bookingRoles = BookingRole::all();
$qualifications = Qualification::all();
return view('bookingdefaults.edit',
compact('bookingDefault', 'locations', 'bookingTypes', 'bookingRoles', 'qualifications'));
}
}
最后来自/resources/views/bookingdefaults/edit.blade.php的观点
@extends('layout')
@section('title')
Staffstuff Edit Booking Default
@stop
@section('php')
{{ $user = Auth::user() }}
@stop
@section('navtag')
<div id="projpage">
@stop
@section('javascript')
@stop
@section('content')
<h2>
<?php // Header: project number and title ?>
@if ($bookingDefault->project->courseNumber)
{{ $bookingDefault->project->courseNumber }}:
@endif
@if ($bookingDefault->project->shortTitle) {{ $bookingDefault->project->shortTitle }}
@elseif ($bookingDefault->project->title) {{ $bookingDefault->project->title }}
@endif
<br />Booking Default:
</h2>
<?php // Form to edit the basic booking info, time, place ?>
{!! Form::model($bookingDefault, ['method' => 'PATCH', 'route' => ['bookingdefaults.update', $bookingDefault->id]]) !!}
{!! Form::hidden('id', $bookingDefault->id) !!}
{!! Form::hidden('project_id', $bookingDefault->project_id) !!}
@include('/partials/bookingdefaultform', ['submit_text' => 'Update Default'])
<div class="form-group">
{!! Form::label('update_existing', 'Update existing bookings (see below): ') !!}
{!! Form::checkbox('update_existing', 'value', TRUE) !!}
<br />Note that NOT updating existing bookings will decouple them from this default and they will need to be updated individually.
</div>
{!! Form::close() !!}
<p>
<a href="{{ route('bookingdefaults.show', $bookingDefault) }}">DONE EDITING</a>
</p>
@stop
确切错误:
ErrorException (E_ERROR)
Trying to get property 'courseNumber' of non-object (View: /Users/redacted/Sites/testproject032418/resources/views/bookingdefaults/edit.blade.php)
答案 0 :(得分:0)
这应该有效:
在RouteServiceProvider
(也可能在routes
中工作)从复数更改为单数并将完整命名空间添加到第二个参数:
Route::model('bookingdefault', App\BookingDefault::class);
// or: Route::model('bookingdefault', 'App\BookingDefault');
其余的都很好。
您可能也需要为其他模型执行此操作。
修改强>
这正是我在测试项目上尝试过的。 GrandChild只是我设置的一些随机模型:
RouteServiceProvider:
public function boot()
{
parent::boot();
Route::model('grandchild', \App\GrandChild::class);
}
路线:
Route::resource('grandchildren', 'GrandChildController');
GrandChildController:
public function show(GrandChild $canBeWhatever)
{
return $canBeWhatever;
}
它有效: