中间件中的隐式路由模型绑定参数问题

时间:2016-07-13 07:02:57

标签: php laravel

我正在制作课程 - 课程 - 问题laravel应用程序。

我有一个像这样的简单课程课程:

class Course extends Model
{
    public $primaryKey = 'course_id';
}

我的路线是这样的:

Route::group(['prefix' => 'Course'], function () {

            Route::group(['prefix' => '/{course}', 'middleware' => 'isThereCourse'], function () {

                Route::get('/', ['uses' => 'CourseController@course_details'])->where('course', '[0-9]+');

                Route::group(['prefix' => 'Lesson'], function () {
                    Route::group(['prefix' => '/{lesson}', 'middleware' => 'isThereLesson'], function () {
                        Route::get('/', ['uses' => 'LessonController@show_for_user']);
                });

           });
});

我希望当用户请求像/Course/5这样的网址向他展示课程详情时。因为我写了course_details这样的功能:

public function course_details (\App\Course $course)
        {
            $course_categories = $course->course_categories()->get(['name'])->lists('name');
            $org_levels        = $course->org_levels()->get(['name'])->lists('name');

            return view('main/pages/course/course-lessons', compact('course', 'course_categories', 'org_levels'));
        }

正如您在course_details及其相关路线Route::get('/', ['uses' => 'CourseController@course_details'])->where('course', '[0-9]+');中看到的那样,我使用隐式模型绑定来访问通过网址发送的课程模型。在这种情况下,一切正常。

现在用户可以继续,并可以显示该课程的课程详细信息。例如,用户可以请求这样的网址:

/Course/5/Lesson/1

为此,我写了另一个名为show的函数:

public function show_for_user ($id, \App\Lesson $lesson)
{
$lesson = Lesson::with(['homeworks', 'files'])->find($lesson->lesson_id);
}

在这种情况下,$id参数是当前课程所属的课程的ID,我想确保课程ID存在。

为此,我写了一个名为isThereCourse的中间件,内容如下:

public function handle($request, Closure $next)
{
      Course::findOrFail($request->course->course_id);
      return $next($request);
}

问题是在中间件中,$request->course引用不同URL中的不同对象。

当打开/Course/5时,$request->course会引用课程模型对象,但在打开/Course/5/Lesson/8时,只会引用课程模型的ID。因此,在不同的url请求isThereCourse中间件上会返回如下错误:

ErrorException in isThereCourse.php line 19:
Trying to get property of non-object

如何管理发送到中间件的参数以便不会发生错误?

2 个答案:

答案 0 :(得分:1)

检查你的中间件。

基本上,您需要在中间件中进行调试,而$ request类本身就是一个对象。所以你必须检查:

dd($request->course->toArray());

如果$request->course给你一个Course类的对象,那么你可以在数组中获取它的输出,以便于理解数据。

我认为这有助于您进行调试。

答案 1 :(得分:1)

我写了这样的中间件:

public function handle ($request, Closure $next)
        {
            $course = $request->course;

            if (
                is_a($course, '\App\Course')
                or
                (is_numeric($course) and !is_null(Course::find($course)))
            ) {
                return $next($request);
            }

            return response()->view('errors/user/403', ['error_msg' => 'Course Not found']);
        }

首先检查作为$course模型实例的Course参数,否则如果是数字,找到具有该ID的Course模型,如果其中一个条件为真,我就完成了请求。