首页  >  文章  >  后端开发  >  laravel5.2-http routing学习

laravel5.2-http routing学习

WBOY
WBOY原创
2016-06-23 13:15:011095浏览

HTTP Routing

Basic Routing

All Laravel routes are defined in the app/Http/routes.phpfile, which is automatically loaded by the framework.路由都被放在routes.php文件中,laravel框架会自动加载此文件。 The most basic Laravel routes simply accept a URI and a Closure, providing a very simple and expressive method of defining routes:

    Route::get('foo', function () {     //get是http的get方法,也可以是post等其他方法    //接收一个url参数为foo的参数,加上闭包匿名函数function(){}          return 'Hello World';         //在function里面用return返回数据给 Route::get('foo')    });

The Default Routes File

By default, the routes.phpfile contains a single route as well as a route groupthat applies the webmiddleware group to all routes it contains. This middleware group provides session state and CSRF protection to routes.

Any routes not placed within the web middleware group will not have access to sessions and CSRF protection,没有中间件的路由组不能访问会话和CSRF保护,so make sure any routes that need these features are placed within the group. 需要确保需要这些功能的路由都放置在路由组中,Typically, you will place most of your routes within this group:

Route::group(['middleware' => ['web']], function () {    //这是路由组route::group,这是中间件['middleware' => ['web']]});

Available Router Methods

The router allows you to register routes that respond to any HTTP verb:

    Route::get($uri, $callback);  //这是get    Route::post($uri, $callback); //这是post    Route::put($uri, $callback); //这是put    Route::patch($uri, $callback); //patch是特殊的,暂时未知    Route::delete($uri, $callback); //这是delete    Route::options($uri, $callback);//这是样例,都可以通过options来填入需要的http路由请求方式

Sometimes you may need to register a route that responds to multiple HTTP verbs. You may do so using the matchmethod. Or, you may even register a route that responds to all HTTP verbs using the anymethod:

Route::match(['get', 'post'], '/', function () {    //这是用match接受访问的方法,匹配[]数组中的方法 });Route::any('foo', function () {      //这是任何方法都可以接受 });

Route Parameters

Required Parameters

1、URI是统一资源标识符,是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。URI由包括确定语法和相关协议的方案所定义。由是三个组成部分:访问资源的命名机制、存放资源的主机名、资源自身的名称,由路径表示。

比如文件的URL,服务器方式用file表示,后面要有主机IP地址、文件的存取路径(即目录)和文件名等信息。有时可以省略目录和文件名,但“/”符号不能省略。

例:file://a:1234/b/c/d.txt代表获取资源使用ftp协议,资源目标是a主机的1234端口的b目录下的c目录下的d.txt。

2、URL是统一资源定位,是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。比如百度URL即是http://www.baidu.com。

Of course, sometimes you will need to capture segments of the URI within your route在uri中捕获变量,即使支持变量传入 For example, you may need to capture a user’s ID from the URL. You may do so by defining route parameters:

Route::get('user/{id}', function ($id) {    return 'User '.$id;    //用的{}来传入变量,将变量传入到function的参数里,function($id),然后传到函数体内,可以通过return返回值,跟普通的函数使用很相似});

You may define as many route parameters as required by your route:

Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {    //支持在一个url内传入多个参数,只要能够跟传入的函数的参数一一对应即可。 });

Route parameters are always encased within “curly” braces(将变量用大括号封装来传递). The parameters will be passed into your route’s Closurewhen the route is executed.

Note:Route parameters cannot contain the -character. Use an underscore ( _) instead.

Optional Parameters

Occasionally you may need to specify a route parameter, but make the presence of that route parameter optional. You may do so by placing a ?mark after the parameter name. Make sure to give the route’s corresponding variable a default value:

Route::get('user/{name?}', function ($name = null) {    //支持默认变量,用?表示,然后在function的传入函数中指定变量的默认值    return $name;});Route::get('user/{name?}', function ($name = 'John') {    return $name;});

Named Routes

Named routes allow the convenient generation of URLs or redirects for specific routes. You may specify a name for a route using the asarray key when defining the route:命名路由,指定一个名字给路由,用as作为数组key来定义

Route::get('profile', ['as' => 'profile', function () {    //这里定义了一个命名路由,路由的名字叫profile,使用的时候可以使用路由的名字profile}]);

You may also specify route names for controller actions:

Route::get('profile', [    'as' => 'profile', 'uses' => 'UserController@showProfile'    //这里指定了路由的名字为profile,也给controller动作指定路由名字,controller动作是@后面的]);

Alternatively, instead of specifying the route name in the route array definition, you may chain the namemethod onto the end of the route definition:

Route::get('user/profile', 'UserController@showProfile')->name('profile');//用name方法来指定路由名字也可以

Route Groups & Named Routes

If you are using route groups, you may specify an askeyword in the route group attribute array, allowing you to set a common route name prefix for all routes within the group:

Route::group(['as' => 'admin::'], function () {//除了可以设置路有名字,也可以设置路由名字前缀,这里设置了前缀admin::    Route::get('dashboard', ['as' => 'dashboard', function () {        // Route named "admin::dashboard"     }]);        //因为这个组有路由前缀admin::,所以里面的路由名字都是带有前缀的,这里的完整的路由名字就是admin::dashboard});

Generating URLs To Named Routes

Once you have assigned a name to a given route, you may use the route’s name when generating URLs or redirects via the global routefunction:

// Generating URLs... $url = route('profile');//一般方式的使用路由名字,这里直接用全局route方法来通过路由名字profile获取url信息,赋值给$url // Generating Redirects...  return redirect()->route('profile'); //也能生成重定向,用redirect()调用route方法来生成重定向,并且用return返回

If the named route defines parameters, you may pass the parameters as the second argument to the routefunction. The given parameters will automatically be inserted into the URL in their correct positions:

Route::get('user/{id}/profile', ['as' => 'profile', function ($id) {    // }]);//路由是包含参数的时候,可以通过{}的方式传递参数$url = route('profile', ['id' => 1]);//在上面设置好传入参数的变量是{id},即id就是变量,那么可以在route()方法里面通过数组传递参数id这个参数,达到传递变量的结果。

Route Groups

Route groups allow you to share route attributes, 路由组允许分享路由属性,例如中间件和命名空间,such as middleware or namespaces, across a large number of routes without needing to define those attributes on each individual(个别的,单独的) route. Shared attributes are specified in an array format as the first parameter to the Route::groupmethod.

To learn more about route groups, we’ll walk through several common use-cases for the feature.

Middleware

To assign middleware to all routes within a group, you may use the middlewarekey in the group attribute array. Middleware will be executed in the order you define this array:

Route::group(['middleware' => 'auth'], function () {//分配了一个中间件auth给这个路由组,那么整个路由组都会受到这个中间件的影响,例如一些页面权限认证就很有用。    Route::get('/', function ()    {        // Uses Auth Middleware     });    Route::get('user/profile', function () {        // Uses Auth Middleware     });});

Namespaces

Another common use-case for route groups is assigning the same PHP namespace to a group of controllers.分配一个php命名空间给一个controller组, You may use the namespaceparameter in your group attribute array to specify the namespace for all controllers within the group:

Route::group(['namespace' =\> 'Admin'], function(){    // Controllers Within The "App\\Http\\Controllers\\Admin" Namespace     //controller包含在命名空间Admin内    Route::group(['namespace' =\> 'User'], function() {        // Controllers Within The "App\\Http\\Controllers\\Admin\\User" Namespace         //controller包含在命名空间User内,而且User在Admin的子层    });});

Remember, by default, the RouteServiceProviderincludes(引入) your routes.phpfile within a namespace group, allowing you to register controller routes without specifying the full App\Http\\Controllersnamespace prefix. So, we only need to specify the portion of the namespace that comes after the base App\Http\\Controllersnamespace.

因为默认情况下,这个RouteServiceProvider引入你的routes.php文件,都在一个命名空间组内,允许你注册controller而不需要指定完全的命名空间前缀,只需要用App\Http\Controllers后面的部分即可。

Sub-Domain Routing

Route groups may also be used to route wildcard(通配符) sub-domains. Sub-domains may be assigned route parameters just like route URIs, allowing you to capture a portion of the sub-domain for usage in your route or controller. The sub-domain may be specified using the domainkey on the group attribute array:

Route::group(['domain' => '{account}.myapp.com'], function () {    //用domain作为数组key,然后值就是子域名,并且传入了参数account,这样实现子域名的匹配,从而实现根据uri中的子域名部分来控制访问,    Route::get('user/{id}', function ($account, $id) {        //     });});

Route Prefixes

The prefixgroup attribute may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:

Route::group(['prefix' => 'admin'], function () {    //设置了一个路由前缀,那么所有的路由都会包含这个前缀,从而简化一些相同的路由输入    Route::get('users', function ()    {        // Matches The "/admin/users" URL     });        //因为有了前缀admin,所以最终的路由生成的是 /admin/users的url});

You may also use the prefixparameter to specify common parameters for your grouped routes:

Route::group(['prefix' =\> 'accounts/{account\_id}'], function () {    Route::get('detail', function ($accountId)    {        // Matches The "/accounts/{account\_id}/detail" URL     });});

CSRF Protection

Introduction

Laravel makes it easy to protect your application from cross-site request forgery(CSRF) attacks. Cross-site request forgeries are a type of malicious exploit whereby unauthorized commands are performed on behalf of an authenticated user.

CSRF是跨站请求攻击,为了防止出现这种情况,这里会在服务器端增加一个csrf的token来验证请求是来自任何的来源的。

laravel自动生成了这个token给每一个活动的用户session

Laravel automatically generates a CSRF “token” for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually making the requests to the application.

Anytime you define a HTML form in your application, you should include a hidden CSRF token field in the form so that the CSRF protection middleware will be able to validate the request. To generate a hidden input field _tokencontaining the CSRF token, you may use the csrf_fieldhelper function:

// Vanilla PHP < ?php echo csrf_field(); ?> php语法 // Blade Template Syntax  {{ csrf_field() }} blade模板语法

The csrf_fieldhelper function generates the following HTML:

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?/>">//调用laravel的一些控件,组件,或者一些方法的时候回自动使用了csrf_token和相关的验证的

You do not need to manually verify the CSRF token on POST, PUT, or DELETE requests. The VerifyCsrfToken middleware, which is included in the webmiddleware group, will automatically verify that the token in the request input matches the token stored in the session.

验证scrftoken的中间件已经默认包含在web这个中间件组里面,所以马上可以使用。

Excluding URIs From CSRF Protection

避免某些uris被csrf保护,例如一些外部的系统和本地的数据进行交互之类。

Sometimes you may wish to exclude a set of URIs from CSRF protection. For example, if you are using Stripeto process payments and are utilizing their webhook system, you will need to exclude your webhook handler route from Laravel’s CSRF protection.

You may exclude URIs by defining their routes outside of the webmiddleware group that is included in the default routes.phpfile, or by adding the URIs to the $exceptproperty of the VerifyCsrfTokenmiddleware:

两种方法:一种是将这些特殊的页面uris信息写到没有被含有csrf功能的路由组之外,例如将他写到另外一个路由组,这个路由组单独服务这些uris,并且使用的中间件没有csrf功能,另外一种方法是在VerifyCsrfToken这个中间件内进行uris排除,写法如下:

< ?phpnamespace App\Http\Middleware;use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;//使用VerifyCsrfToken这个中间件,并且命名为BaseVerifierclass VerifyCsrfToken extends BaseVerifier //继承BaseVerifier,重写VerifyCsrfToken{    /**     * The URIs that should be excluded from CSRF verification.     *     * @var array     */    protected $except = [ //将排除方法写到里面,固定格式。        'stripe/*',    ];}

X-CSRF-TOKEN

In addition to checking for the CSRF token as a POST parameter, the Laravel VerifyCsrfTokenmiddleware will also check for the X-CSRF-TOKENrequest header. You could, for example, store the token in a “meta” tag:

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

Once you have created the metatag, you can instruct a library like jQuery to add the token to all request headers. This provides simple, convenient CSRF protection for your AJAX based applications:

$.ajaxSetup({        headers: {            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')            //用meta标签来标识csrf-token,用于javascript里面的数据传递,并且是在header里面的        }});

X-XSRF-TOKEN

Laravel also stores the CSRF token in a XSRF-TOKENcookie. You can use the cookie value to set the X-XSRF-TOKENrequest header. Some JavaScript frameworks, like Angular, do this automatically for you. It is unlikely that you will need to use this value manually.

Route Model Binding

模型绑定,例如插入一个Eloquent model 实例

Laravel route model binding provides a convenient way to inject model instances into your routes. For example, instead of injecting a user’s ID, you can inject the entire Usermodel instance that matches the given ID.

Implicit Binding

Laravel will automatically resolve type-hinted(类型暗示) Eloquent models defined in routes or controller actions whose variable names match a route segment name. For example:laravel会自动解析这些带有暗示的模型

Route::get('api/users/{user}', function (App\User $user) {//自动解析App\User Eloquent models,返回一个$user对象,而这个$user是跟uris里面的{user}是一致的,有值得话然后传递给function,如果这个模型找不到值得话,会自动返回404,其实这里相当于,一个普通的值传递给路由的function,而这个值现在替换为一个laravel的模型,简化了代码逻辑    return $user->email;});

In this example, since the Eloquent type-hinted $uservariable defined on the route matches the {user}segment in the route’s URI, Laravel will automatically inject the model instance that has an ID matching the corresponding value from the request URI.

If a matching model instance is not found in the database, a 404 HTTP response will be automatically generated.

Customizing The Key Name

If you would like the implicit model binding to use a database column other than idwhen retrieving models, you may override the getRouteKeyNamemethod on your Eloquent model:

/** * Get the route key for the model. * * @return string */public function getRouteKeyName(){//通过重写Eloquent model的getRouteKeyName方法可以改变模型绑定的名字,这里改成slug    return 'slug';}

Explicit Binding

显示绑定

To register an explicit binding, use the router’s modelmethod to specify the class for a given parameter. You should define your model bindings in the RouteServiceProvider::bootmethod:

在RouteServiceProvider.php文件中

Binding A Parameter To A Model

public function boot(Router $router){    parent::boot($router);    $router->model('user', 'App\User');    //使用model方法为给定的参数绑定类,这里为user参数绑定了一个App\User}

Next, define a route that contains a {user}parameter:

$router->get('profile/{user}', function(App\User $user) {    //然后这里就可以使用{user}参数了    //由于我们已经绑定 {user} 参数到 App\User 模型,User 实例会被注入到该路由。因此,如果请求 URL 是 profile/1,就会注入一个用户 ID 为 1 的 User 实例。    });

Since we have bound the {user}parameter to the App\Usermodel, a Userinstance will be injected into the route. So, for example, a request to profile/1will inject the Userinstance which has an ID of 1.

If a matching model instance is not found in the database, a 404 HTTP response will be automatically generated. 如果没有找到匹配的数据,404请求也会自动生成并重定向。

Customizing The Resolution Logic

If you wish to use your own resolution logic, you should use the Route::bindmethod. The Closure you pass to the bindmethod will receive the value of the URI segment, and should return an instance of the class you want to be injected into the route:

如果想用自定义的逻辑,你需要用Route::bind方法

$router->bind('user', function($value) {//这里会将user传递到闭包的$value,然后返回你想要在该路由中注入的类实例    return App\User::where('name', $value)->first();    //这里返回的是一个实例class});

Customizing The “Not Found” Behavior

自定义not found的行为

If you wish to specify your own “not found” behavior, pass a Closure as the third argument to the modelmethod:

$router->model('user', 'App\User', function() {    throw new NotFoundHttpException;    //将封装行为的闭包传递给model方法,并且作为第三个参数传入});

Form Method Spoofing

HTML forms do not support PUT, PATCHor DELETEactions. So, when defining PUT, PATCHor DELETEroutes that are called from an HTML form, you will need to add a hidden _methodfield to the form. The value sent with the _methodfield will be used as the HTTP request method:

form表单不支持put patch delete这样的行为,你可以增加一个隐藏字段_method 给表单,这样的话,表单会发送这个字段给服务器,php服务器会进行识别。

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

To generate the hidden input field _method, you may also use the method_fieldhelper function:

< ?php echo method_field('PUT'); ?>

Of course, using the Blade templating engine:

{{ method_field('PUT') }}

Accessing The Current Route

The Route::current()method will return the route handling the current HTTP request, allowing you to inspect the full Illuminate\Routing\Routeinstance:

这个方法会返回路由正在处理的http请求,允许你注入完整的Illuminate\Routing\Route 实例

$route = Route::current();$name = $route->getName();$actionName = $route->getActionName();

You may also use the currentRouteNameand currentRouteActionhelper methods on the Routefacade to access the current route’s name or action:

$name = Route::currentRouteName();$action = Route::currentRouteAction();

Please refer to the API documentation for both the underlying class of the Route facadeand Route instanceto review all accessible methods.

参考引用:

https://laravel.com/docs/5.2/routing

http://laravelacademy.org/post/2784.html

本文由 PeterYuan 创作,采用 署名-非商业性使用 2.5 中国大陆 进行许可。 转载、引用前需联系作者,并署名作者且注明文章出处。神一样的少年 » laravel5.2-http routing学习

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn