Laravel 4 定义 RESTful 控制器

Posted

技术标签:

【中文标题】Laravel 4 定义 RESTful 控制器【英文标题】:Laravel 4 defining RESTful controllers 【发布时间】:2013-08-26 11:22:08 【问题描述】:

所以我是 Laravel 框架 v4 的新手,想知道创建和使用 RESTful 控制器的方法是什么。通读文档,我对 RESTful 控制器和资源控制器之间的区别有点困惑。

根据文档定义 RESTful 控制器时,建议在 routes.php 中执行以下操作:

Route::controller('posts', 'PostController');

PostController 中,我们是否通过在方法名称前加上我们希望使用的 HTTP 动词来定义类方法?例如:

class PostController extends \BaseController 
    public function getIndex()
    
        //
    

但是,它还概述了在 routes.php 文件中创建资源控制器的方法,如下所示: Route::resource('posts', 'PostController');

PostController.php 中,我们定义方法时不使用 HTTP 动词作为前缀。

class PostController extends \BaseController 
    public function index()
    
        //
    

这两者有什么区别?我们什么时候用一种代替另一种,为什么?

另外,我们应该使用Route::controller('posts', 'PostController');Route::resource('posts', 'PostController'); 将路由传递给控制器​​,还是应该手动定义每个路由,如下所示:

Route::get('/users', 'UserController@index');
Route::get('/users/create', 'UserController@create');
Route::post('/users', 'UserController@store');
Route::get('/users/id', 'UserController@show');
Route::get('/usersid/edit', 'UserController@edit');
Route::put('/users', 'UserController@update');
Route::delete('/users', 'UserController@destroy');

【问题讨论】:

后者,Route::resource,根据文档 - 除非您需要更多控制。 :) 那么使用Route::controller('posts', 'PostController');不应该用来创建RESTful控制器?我们也不应该在控制器方法前加上适当的 HTTP 动词吗?我意识到最后一个问题可能不适合这种格式,因为它是主观的。 【参考方案1】:

以这个控制器为例:

<?php

class TestController extends BaseController 

    public function getIndex()
    
        echo "a";
    

    public function postSecond($a)
    
        echo "b";
    


在你的路线中,如果你有

Route::controller('tests', 'TestController');

然后执行

php artisan routes

你将拥有:

+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
| Domain | URI                                        | Name                   | Action                            | Before Filters | After Filters |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
|        | GET /tests/index/v1/v2/v3/v4/v5  |                        | TestController@getIndex           |                |               |
|        | GET /tests                                 |                        | TestController@getIndex           |                |               |
|        | POST /tests                                | tests.store            | TestController@store              |                |               |
|        | GET /tests/_missing                      |                        | TestController@missingMethod      |                |               |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+

Laravel 检查控制器并根据它找到的方法自动生成路由。

如果你这样做了

Route::resource('tests', 'TestController');

您将获得以下路线列表:

+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
| Domain | URI                                        | Name                   | Action                            | Before Filters | After Filters |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
|        | GET /tests                                 |                        | Closure                           |                |               |
|        | GET /tests                                 | tests.index            | TestController@index              |                |               |
|        | GET /tests/create                          | tests.create           | TestController@create             |                |               |
|        | POST /tests                                | tests.store            | TestController@store              |                |               |
|        | GET /tests/tests                         | tests.show             | TestController@show               |                |               |
|        | GET /tests/tests/edit                    | tests.edit             | TestController@edit               |                |               |
|        | PUT /tests/tests                         | tests.update           | TestController@update             |                |               |
|        | PATCH /tests/tests                       |                        | TestController@update             |                |               |
|        | DELETE /tests/tests                      | tests.destroy          | TestController@destroy            |                |               |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+

不用猜,La​​ravel 使用预定义的 CRUD 路由列表,您可以删除其中一些路由,但它不会检查您的控制器来为您的方法构建路由。

您决定什么是最适合您的。但是,通常,如果您的控制器是 CRUD 控制器,Route::resource() 是一个好的开始,否则您可以使用 Route::controller() 或手动构建路由。

编辑:

没有真正的为什么一个或为什么另一个,只是设计和选择的问题。有些人永远不会使用它们。这只是帽子Route::resource() 遵循Rails 的路由方式:http://guides.rubyonrails.org/routing.html

使用 Route::resource() 你不需要创建所有这些方法,但你最终会得到一个毫无意义的路由列表,因为 Laravel 总是默认创建所有这些,除非你这样做:

Route::resource('photo', 'PhotoController',
                array('only' => array('index', 'show')));

您的路线列表将仅显示索引并显示操作。

另外,如果您需要一些其他路线,使用Route::resource() 您必须手动构建它们或使用一些魔法使它们自动用于您所有资源丰富的路线。使用Route::controller() 一切都是自动的,每次添加新方法时,都会为您创建一条新路线。

同样,如果您要构建 CRUD 控制器,请从使用 Route::resource() 开始。否则,请考虑在您的特定情况下一种或另一种的好处。

编辑2:

这是一篇很棒的文章,来自 Phil Sturgeon(PyroCMS 和 PHP-FIG),关于手动构建所有路由的好处:http://philsturgeon.co.uk/blog/2013/07/beware-the-route-to-evil。

【讨论】:

我不太确定我是否理解您的回答。如果它们都实现相同的目标,我为什么要使用 Route::controller 而不是 Route::resourceRoute::controller 似乎是设置 RESTful 控制器的一个更复杂的过程,因为它需要打破约定并在控制器方法前加上 HTTP 动词。有什么理由在Route::resource 上使用它吗?如果我使用Route::resource,我就不必拥有用于索引、创建、存储、显示、编辑、更新和销毁的控制器方法,对吗?添加或删除方法将反映在可用的路由中? 好的,据我了解,Route::controller 检查控制器并根据它找到的方法生成路由,而Route::resource 生成预定义的可用路由列表。那么,我的问题是,如果我使用Route::resource('posts', 'PostController') 并向PostController.php 添加或删除方法,Laravel 会检查控制器并创建或删除路由吗?假设我将方法 archive() 添加到 PostsController.php - Laravel 会将 /posts/archive/ 添加到我的可用路由中,还是必须通过 Route::get() 手动指定?在 routes.php 中? 另外,这是一篇很棒的文章,我想我可能会手动定义路由,而不是依赖Route::controllerRoute::resource。我可以使用php artisan controller:make x 生成脚手架并在我的routes.php 文件中相应地映射到它。这似乎是一种合理的做法? Laravel 只会检查 'Route::controller' 上的控制器方法。 'Route::resource' 创建的所有路由都在路由器类中预定义。它不会检查您的控制器以查找新路线。要改变这一点,您需要扩展该类并用您自己的替换 Laravel 路由器。 artisan controller:make 是一个很好的生成器,有时您可能需要删除一些样板代码,但是当您需要完整的 CRUD 控制器时它会很有帮助,或者您可以使用选项来生成您需要的那些方法。 好吧,现在一切都说得通了 - tyvm :)【参考方案2】:

@Antonio 的回答很好。让我更简洁地说一些类似和重要的事情。在 routes.php 中:

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

使用资源方法使 Laravel 承担 CRUD 功能,它只查找它的六个预制 CRUD 方法:索引、创建、存储、显示、销毁等。它不会“看到”任何其他新方法你在那里创造。

Route::controller('info', 'InfoController');

使用控制器方法允许您创建自定义方法/页面。当您在方法/页面名称前加上 HTTP 动词时,Laravel 会查找它们。在你的 XxxxController.php 中:

class InfoController extends \BaseController 

    public function getFeatures()
    
        return View::make('info.features');
    

    public function getContactUs()
    
        return View::make('info.contact-us');
    

    public function getPricing()
    
        return View::make('info.pricing');
    


【讨论】:

以上是关于Laravel 4 定义 RESTful 控制器的主要内容,如果未能解决你的问题,请参考以下文章

Laravel RESTful API 版本控制设计

未找到 Laravel RESTful 控制器方法

Laravel 4:如何为嵌套资源编写正确的嵌套控制器?

在 Laravel 5.2 中通过 RESTful 资源控制器使用 jQuery Ajax Post 方法将数据存储在数据库中

Laravel RESTful 返回 301 状态

如何在 Laravel 4 中使用 RESTful API? [关闭]