HTTP 路由

未匹配的标注
本文档最新版为 6.x,旧版本可能放弃维护,推荐阅读最新版!

HTTP 路由

基本路由

你可以在 app/Http/routes.php 文件中定义应用程序的大多数路由,该文件将会被 bootstrap/app.php 文件加载。最基本的 Lumen 路由仅接受 URI 和一个闭包

$app->get('/', function () {
    return 'Hello World';
});

$app->post('foo/bar', function () {
    return 'Hello World';
});

$app->put('foo/bar', function () {
    //
});

$app->delete('foo/bar', function () {
    //
});

生成 URLs 路由

你可以通过 url 辅助函数生成应用程序路由:

$url = url('foo');

路由参数

基础路由参数

有时候你可能需要在你的 URI 路由中来获取一些参数。例如,从 URL 获取用户的 ID。这时可通过自定义路由参数来获取:

$app->get('user/{id}', function ($id) {
    return 'User '.$id;
});

你可以依照路由需要,定义任意数量的路由参数:

$app->get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

路由的参数都会被放在「大括号」内。当运行路由时,参数会通过路由闭包来传递。

注意:路由参数不能包含 - 字符。请用下划线 (_) 替换。

正则表达式限制参数

你可以在路由实例上使用 where 方法来限制路由参数格式。where 方法接受参数的名称和定义参数应该如何被限制的正则表达式:

$app->get('user/{name:[A-Za-z]+}', function ($name) {
    //
});

命名路由

命名路由让你可以更方便的为特定路由生成 URL 或进行重定向。你可以使用 as 数组键指定名称到路由上:

$app->get('user/profile', ['as' => 'profile', function () {
    //
}]);

还可以指定路由名称到控制器动作:

$app->get('user/profile', [
    'as' => 'profile', 'uses' => 'UserController@showProfile'
]);

对命名路由生成 URLs

一旦你在指定的路由中分配了名称,则可通过 route 函数来使用路由名称生成 URLs 或重定位:

$url = route('profile');

$redirect = redirect()->route('profile');

如果路由定义了参数,那么你可以把参数作为第二个参数传递给 route 方法。指定的参数将自动加入到 URL 中:

$app->get('user/{id}/profile', ['as' => 'profile', function ($id) {
    //
}]);

$url = route('profile', ['id' => 1]);

路由群组

路由群组允许你共用路由属性,例如:中间件、命名空间,你可以利用路由群组到多个路由中套用这些属性,而不需在每个路由上都设置一次。共用属性被指定为数组格式,当作 $app->group 方法的第一个参数。

为了了解更多路由群组的相关内容,我们可通过几个常用样例来熟悉这些特性。

中间件

要想指定中间件到所有群组内的路由中,则可以在群组属性数组里使用 middleware 参数。中间件将会依照列表内指定的顺序运行:

$app->group(['middleware' => 'auth'], function ($app) {
    $app->get('/', function ()  {
        // Uses Auth Middleware
    });

    $app->get('user/profile', function () {
        // Uses Auth Middleware
    });
});

命名空间

另一个常见的例子是,指定相同的 PHP 命名空间给控制器群组。可以使用 namespace 参数来指定群组内所有控制器的命名空间:

$app->group(['namespace' => 'App\Http\Controllers\Admin'], function ($app) {

    // Controllers Within The "App\Http\Controllers\Admin" Namespace

});

路由前缀

通过路由群组数组属性中的 prefix,在路由群组内为每个路由指定的 URI 加上前缀。例如,你可能想要在路由群组中将所有的路由 URIs 加上前缀 admin

$app->group(['prefix' => 'admin'], function ($app) {
    $app->get('users', function ()  {
        // Matches The "/admin/users" URL
    });
});

你也可以使用 prefix 参数去指定路由群组中共用的参数:

$app->group(['prefix' => 'accounts/{account_id}'], function ($app) {
    $app->get('detail', function ($account_id)  {
        // Matches The accounts/{account_id}/detail URL
    });
});

CSRF 保护

注意: 你必须开启 会话 才能使用此功能。

介绍

Lumen 提供简单的方法保护你的应用程序不受到 跨网站请求伪造 攻击。跨网站请求伪造是一种恶意的攻击,借以通过身份验证的用户身份来运行未经授权的命令。

Lumen 会自动生成一个 CSRF token 给每个受应用程序管理的活动用户的 Session。该 token 用来验证用户是否为实际发出请求的用户。若要生成一个包含 CSRF token 的 _token 隐藏输入字段,可以使用 csrf_field 辅助函数:

<?php echo csrf_token(); ?>

csrf_field 辅助函数生成以下的 HTML:

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

你不需要手动验证 POST、PUT 或 DELETE 请求的 CSRF token。在 VerifyCsrfToken HTTP 中间件 将自动验证请求与 session 中的 token 是否相符。

X-CSRF-TOKEN

除了检查 CSRF token 是否被当作 POST 参数之外,在 Lumen VerifyCsrfToken 中间件也会检查请求标头中的 X-CSRF-TOKEN。例如,你可以将其保存在 meta 标签中:

<meta name="csrf-token" content="{{ csrf_token() }}">

一旦你创建了 meta 标签,你就可以使用 jQuery 之类的函数库将 token 加入到所有的请求标头。基于 AJAX 的应用,提供了简单、方便的 CSRF 保护:

$.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
});

X-XSRF-TOKEN

Lumen 也会在 XSRF-TOKEN cookie 中保存 CSRF token。你也可以使用 cookie 的值来设置 X-XSRF-TOKEN 请求标头。一些 JavaScript 框架会自动帮你处理,例如:Angular。你不大可能会需要手动去设置这个值。

跨站请求伪造

HTML 表单没有支持 PUTPATCHDELETE 动作。所以在从 HTML 表单中调用被定义的 PUTPATCHDELETE 路由时,你将需要在表单中增加隐藏的 _method 字段。跟随 _method 字段送出的值将被作为 HTTP 的请求方法使用:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

抛出 404 错误

这里有两种方法来从路由手动触发 404 错误。首先,你可以使用 abort 辅助函数。abort 辅助函数只是简单的抛出一个带有指定状态代码的 Symfony\Component\HttpFoundation\Exception\HttpException

abort(404);

其次,你也可以手动抛出 Symfony\Component\HttpKernel\Exception\NotFoundHttpException 的实例。

更多有关如何操作 404 异常和自定义响应,可以到 错误 章节内参考文档。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~