laravel5.5学习2-路由系统
一、初识路由
路由系统是所有 PHP 框架的核心,路由承载的是 URL 到代码片段的映射,不同的框架所附带的路由系统是这个框架本质最真实的写照,一丝不挂,一览无余。Laravel 路由中文文档:http://laravel-china.org/docs/5.5/routing
Laravel 5.3 之后就把路由放到了 learnlaravel5/routes
文件夹中,一共有四个文件。
我们先看一下web.php
中仅存的几行代码:
Route::get('/', function () {
return view('welcome');
}); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home');
中间的一行代码 Auth::routes();
就是 Auth 系统自动注入的路由配置,我们不用深究,我们的注意力主要集中头三行和最后一行代码上。
二、命名空间
我一直认为 Laravel 5 除了性能大幅提升之外相对于 4 最大的进步就在于新的命名空间规划:更清晰,更合理,更有利于新手。
Laravel 4 失败的简洁
Laravel 4 时代,大量的代码都运行在根命名空间下,路由、Controller、Model 等等。看起来这么做可以少写几行枯燥的 use xxxx;
,实则是对于命名空间的误使用,而且对于新手学习命名空间是有毒的。
绝对类名
Laravel 5 全面引入了 psr-4 命名空间标准:命名空间和实际文件所在的文件夹层级一致,文件夹首字母大写,并自动成为此文件的约定命名空间。举个小栗子:learnlaravel5/app/Http/Controllers/HomeController.php
的绝对类名为:\App\Http\Controllers\HomeController
,learnlaravel5/app/User.php
的绝对类名为:\App\User
。(实际上 psr-4 是自动加载标准,用在这里故称其为命名空间标准。)
“绝对类名”是我自创的:在启用了命名空间的系统中,子命名空间下的类有一个全局都可以直接访问的名称,这个名称就是该类的命名空间全称。虽然命名空间在“实用主义”的 PHP 语言里看起来十分古怪,不过他也还是 PHP 嘛,依然遵循 PHP 的运行原理和哲学。同理,Laravel 无论多么强大,他都是 PHP 代码写成的,所以当你苦于 Laravel 没有提供某个你需要的功能时,不要惊慌不要着急,just write your PHP code。
三、基础路由解析
1、闭包路由
路由文件中前三行即为闭包路由:
Route::get('/', function () {
return view('welcome');
});
闭包路由使用闭包作为此条请求的响应代码,方便灵活,很多简单操作直接在闭包里解决即可。例如“输出服务器当前时间”:
Route::get('now', function () {
return date("Y-m-d H:i:s");
});
如果你想得到北京时间,请在 learnlaravel5/config/app.php
第 68 行左右把 timezone 设置为上海:
'timezone' => 'Asia/Shanghai',
3、控制器@方法 路由
闭包路由虽然灵活强大,不过大多数场景下我们还是需要回归到 MVC 架构的:
Route::get('/home', 'HomeController@index')->name('home');
这行路由代码的意思想必大家都能猜到一二了:当以 GET 方法访问 http://fuck.io:1024/home
的时候,调用 HomeController 控制器中的 index 方法(函数)。同理,你可以使用 Route::post('/home', 'HomeController@indexPost');
响应 POST 方法的请求。最后的->name()
不是必须的,感兴趣可以自己了解。
控制器@方法 调用原理浅析
Laravel 的路由跟所有 PHP 框架的路由一样,都是用的最简单直接的 PHP 方式来调用控制器中的方法的:使用字符串初始化类得到对象,调用对象的指定方法,返回结果。下面我简单罗列几步对 Laravel 路由调用过程的探测,感兴趣的话可以自己研究。
learnlaravel5/app/Providers/RouteServiceProvider.php
全局搜索 routes.php
,我们找到了这个文件。此文件最后的 mapWebRoutes 方法,给所有的路由统一加进了一个路由组,定义了一个命名空间和一个中间件:
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
顺着这个函数往上看,你会发现命名空间定义的地方:
protected $namespace = 'App\Http\Controllers';
之后命名空间、类、方法是如何传递的呢?
learnlaravel5/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php
经过简单的追踪,我们找到了这个文件。让我们在 dispatch 方法中增加一行 var_dump($controller);
,刷新http://127.0.0.1:8000:1024/home
就可以看到页面上如下的输出:
开头的App\Http\Controllers\HomeController
就是我们要调用的控制器类的“绝对类名”,注意这里是不带\
根命名空间符号的。
四、增加路由组
路由组可以给组内路由一次性增加 命名空间、uri 前缀、域名限定、中间件 等属性,并且可以多级嵌套,异常强大。
如:我们要使用路由组来将后台页面置于“需要登录才能访问”的中间件下,以保证安全。在Routes/web.php 里增加下面三行:
Route::group(['middleware' => 'auth', 'namespace' => 'Admin', 'prefix' => 'admin'], function() {
Route::get('/', 'HomeController@index');
});
命名空间
另一个常见用例是使用 namespace
方法将相同的 PHP 命名空间分配给路由组的中所有的控制器:
Route::namespace('Admin')->group(function () {
// 在 "App\Http\Controllers\Admin" 命名空间下的控制器
});
请记住,默认情况下,RouteServiceProvider
会在命名空间组中引入你的路由文件,让你不用指定完整的 App\Http\Controllers
命名空间前缀就能注册控制器路由。因此,你只需要指定命名空间 App\Http\Controllers
之后的部分。
五、CSRF 保护
指向 web
路由文件中定义的 POST
、PUT
或 DELETE
路由的任何 HTML 表单都应该包含一个 CSRF 令牌字段,否则,这个请求将会被拒绝。可以在 CSRF 文档 中阅读有关 CSRF 保护的更多信息:
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
六、表单方法伪造
HTML 表单不支持 PUT
、PATCH
或 DELETE
行为。所以当你要从 HTML 表单中调用定义了 PUT
、PATCH
或 DELETE
路由时,你将需要在表单中增加隐藏的 _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>
你也可以使用辅助函数 method_field
来生成隐藏的 _method
输入标签:
{{ method_field('PUT') }}
laravel5.5学习2-路由系统的更多相关文章
- python 学习笔记十六 django深入学习一 路由系统,模板,admin,数据库操作
django 请求流程图 django 路由系统 在django中我们可以通过定义urls,让不同的url路由到不同的处理函数 from . import views urlpatterns = [ ...
- ASP.NET MVC4学习笔记路由系统实现
一.路由实现 路由系统实际是一个实现了ASP.NET IHttpModule接口的模块,通过注册HttpApplication的PostResolveRequestCache 事件对Url路由处理.总 ...
- ASP.NET MVC4学习笔记路由系统概念与应用篇
一.概念 1.路由是计算机网络中的一个技术概念,表示把数据包从一个网段转发至另一网段.ASP.NET中的路由系统作用类似,其作用是把请求Url映射到相应的"资源"上,资源可以是一段 ...
- Python学习---Django路由系统【all】
Django URL (路由系统) Django URL (路由系统): URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL模式以及要为该URL模式调用的视图函数之间的映 ...
- Django学习之路由系统
一.Django的路由系统 1.URLconf配置 基本格式: 参数说明: 2.正则表达式详解 基本配置 注意事项 补充说明 3.分组命名匹配 URLconf匹配的位置 捕获的参数永远都是字符串 视图 ...
- vue学习之六路由系统
一.vueRouter实现原理 VueRouter的实现原理是根据监控锚点值的改变,从而不断修改组件内容来实现的,我们来试试不使用VueRouter,自己实现路由控制,如下代码: <!DOCTY ...
- Laravel5.1学习笔记i14 系统架构6 Facade
Facades 介绍 使用 Facades Facade 类参考 #介绍 Facades provide a "static" interface to classes th ...
- Laravel5.1学习笔记13 系统架构5 Contract
Contract 简介 为什么要用 Contract? Contract 参考 如何使用 Contract 简介 Laravel 中的 Contract 是一组定义了框架核心服务的接口.例如,Illu ...
- Laravel5.1学习笔记12 系统架构4 服务容器
Service Container 介绍 绑定的用法 绑定实例到接口 上下文绑定 标签 解析 容器事件 #介绍 The Laravel service container is a powerful ...
随机推荐
- 【LOJ2604】「NOIP2012」开车旅行
[题目链接] [点击打开链接] [题目大意] 从西到东的坐标轴\([1,n]\)上有\(n\)个海拔互不相同的城市,每两个城市之间的距离定义为\(dis(i,j)=|h_i-h_j|\) 小\(A\) ...
- oracle ROW_NUMBER() OVER(PARTITION BY '分组' ORDER BY '排序' DESC) 用法
转载:https://blog.csdn.net/dbagaoshou/article/details/51330829 SELECT * FROM ( SELECT ROW_NUMBER() OVE ...
- python学习之路(13)
列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, ...
- [清华集训2016]温暖会指引我们前行——LCT+最大生成树
题目链接: [清华集训2016]温暖会指引我们前行 题目大意:有$n$个点$m$次操作,每次操作分为三种:1.在$u,v$两点之间连接一条编号为$id$,长度为$l$,温度为$t$的边.2.查询从$u ...
- springboot+mybatis 使用事务
一.一些概念 声明式的事务管理是基于AOP的,在springboot中可以通过@Transactional注解的方式获得支持,这种方式的优点是: 1)非侵入式,业务逻辑不受事务管理代码的污染. 2)方 ...
- Oracle三种分页?
①select * from (select employee.*, rownum r from employee) where r between 2 and 5; ②select * from ( ...
- GC类型以及不同类型GC的搭配 1
jvm内存分配,以及gc算法在上两篇博客中已经有所介绍.接下来我们重点分析不同gc器的特点和他们的搭配使用(并非任何一种新生代GC策略都可以和另一种年老代GC策略进行配合工作)
- JAVA-ThreadPoolExecutor 线程池
一.创建线程池 /** * @param corePoolSize 核心线程池大小 * 当提交一个任务到线程池时,如果当前 poolSize < corePoolSize 时,线程池会创建一个线 ...
- committed与urgent的区别
Committed跟Urgent都是time automaton 中用来表示state的关键词. 它们的主要区别是: Committed前后的两个状态改变(transition)是串行发生,不可打断的 ...
- 阶段3 3.SpringMVC·_01.SpringMVC概述及入门案例_09.RequestMapping注解的属性
看下RequestMapping下面 一共有几个属性 那么属性用处不大 value和path互相为别名 这里用value表示path也是没有问题的 只有一个属性,并且属性名称叫做value那么就可以省 ...