【问题标题】:Laravel 5.5 Resource Controller and Dependecy InjectionLaravel 5.5 资源控制器和依赖注入
【发布时间】:2018-05-17 07:44:55
【问题描述】:

我正在开发一个 Laravel 5.5 应用程序。当我使用php artisan make:model SomeModel -mr 时,它会创建模型、迁移和资源控制器。

我注意到有些方法默认只有一个参数:模型:

public function show(SomeModel $someModel)
{
    ...
}

如果您查看 $someModel 变量,它有一个空的 SomeModel 对象。

我正在阅读 Laravel 文档,它看起来像容器或外观,但我不确定如何使用它。你呢?

编辑 1:

我的路由在 routes/web.php 中定义为:Route::resource('users', 'UserController');

现在我不得不手动定义所有路由,因为自动绑定不起作用:

Route::get('users', 'UserController@index');
Route::get('users/create', 'UserController@create');
Route::post('users', 'UserController@store');
Route::get('users/{user}/edit', 'UserController@edit', function(App\User $user) {});
Route::post('users/{user}', 'UserController@update', function(App\User $user) {});
Route::post('users/{user}/delete', 'UserController@destroy', function(App\User $user) {});

那么,我应该像这样将每个资源控制器路由替换为手动路由吗?

【问题讨论】:

    标签: php laravel laravel-5 dependency-injection containers


    【解决方案1】:

    资源控制器希望您使用route model binding。在您的路由文件中,与注入模型的控制器操作对应的每个路由都需要具有匹配的参数。

    例如:

    Route::get('user/{user}', 'UserController@show');
    

    使用上述路由,以下控制器操作将接收与作为 URL 参数传递的用户 ID 对应的用户实例。

    class UserController extends Controller
    {
        public function show(User $user)
        {
           ...
        }
    }
    

    您现在看到一个空模型的原因是 Laravel 只会将新模型传递给控制器​​,如果它没有绑定到路由参数。换句话说,如果您忘记在路由文件中绑定模型 automatic injection 只会给您一个新实例。

    请注意,如果您使用的是路由资源,则生成的路由应该已经具有正确的参数

    Route::resource('users', 'UserController');
    

    您可以运行php artisan route:list 来确认您的实际路线是否正确。

    【讨论】:

    • 感谢您的回复。在我的路由中,它被定义为Route::resource('users', 'UserController');,因此例如当我访问 URL user/1 时,它应该将路由绑定到操作UserController@show。我尝试的是在方法中包含一个额外的参数:public function show($id, User $user) 所以$id 是 1(它可以工作)。但是$user什么都没有。
    • @Maramal 运行php artisan route:list 会得到什么。您应该注入 $id 或 $user,而不是两者。
    • 它定义正确,因为我正在访问该方法。但以防万一:users/{user}/ | users.edit | App\Http\Controllers\UserController@show
    • 我想只使用User实例,但如果我不能我需要使用id,但我想先了解它。
    • @Maramal 您的型号名称是否与您的路线参数匹配?如果路由是users/{user},那么模型类名必须是User,除非您在模型中声明getRouteKeyName() 方法。
    【解决方案2】:

    您的问题是您的控制器需要如下两个参数:

       public function show($id, User $user)
    

    如果你尝试:

       public function show(User $user)
    

    它应该可以正常工作。

    在您的路线中,您只传递了一个参数,例如:

    user/{user}
    

    所以如果你 dd 第一个参数它会显示数字 1 但如果你通过了 到模型,它将根据您在路由中传递的 id 返回相应的用户。

    User 模型返回空对象的原因是没有传递给它的值。 还要确保您的路线占位符:/{user} 与中的变量名匹配 控制器:public function show(User $user).

    希望这会有所帮助。

    【讨论】:

    • 当我生成控制器时,它只有一个参数:show(User $user)。我试图弄清楚,这就是为什么我将两个参数传递给它,但只有一个参数是行不通的。如果我这样做show(User $id),,它将返回给我一个空对象。
    • 这是不正确的。没有什么可以阻止您同时注入原始路由参数和绑定模型。
    • 当然你可以根据需要添加任意数量的参数,但请确保将路由 /user/{user} 与模型用户 $user 匹配,路由参数占位符应与用于绑定模型。
    • @DevinNorgarb 我不明白将public function show($id, User $user) 更改为public function show(User $user) 的建议如果路由模型绑定正常工作,那么这两个都可以工作。
    • 据我了解,您将传递给路线中的几个参数。然后它看起来像user/{id}/{user}。您确定路由中的占位符与您在控制器中输入提示的变量名称匹配吗?
    【解决方案3】:

    我也遇到了同样的问题。 如果你的模型有两个或更多的单词,你只需要使用像 $modeModel 这样的小写字母作为 $somemodel。

    public function show(SomeModel $somemodel)
    {
        ...
    }
    

    【讨论】:

    • 这只是一个例子......而且我认为它没有任何关系或它是正确的。
    • 这是一个已报告的错误。 github.com/laravel/framework/issues/18167
    • 好吧...但我没有真正的“someModel”,我只是用它作为例子。还是谢谢...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2018-05-21
    • 1970-01-01
    • 2023-04-06
    • 2016-02-01
    • 2018-10-22
    相关资源
    最近更新 更多