Laravel 4定义了RESTful控制器

时间:2013-08-23 11:59:38

标签: rest laravel laravel-4 laravel-routing

所以我从第4版开始就是Laravel框架的新手,想知道创建和使用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('/users{id}/edit', 'UserController@edit');
Route::put('/users', 'UserController@update');
Route::delete('/users', 'UserController@destroy');

2 个答案:

答案 0 :(得分:35)

以此控制器为例:

<?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            |                |               |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+

不用猜测,Laravel使用预定义的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()。否则,请考虑您的具体情况中的一方或另一方的好处。

EDIT2:

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

答案 1 :(得分:6)

@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');
    }

}