laravel路由、中间件、控制器等简单笔记

来源:互联网 发布:淘宝店铺如何查排名 编辑:程序博客网 时间:2024/05/29 18:36
1.基本路由 - http://laravelacademy.org/post/398.htmlget()post()put()patch()delete()options()match() - ['get', 'post']any() - 任意http方法路由参数 - 普通参数 {name}路由参数 - 可选约束 {name?}路由参数 - 正则约束 - {name} + 链式where(name)路由参数 - 正则约束 - 全局约束(所有路由都会进行正则约束) - RouteServiceProvider->boot()里添加 $router->pattern('name', '\w{6}')2.路由命名和路由分组 - http://laravelacademy.org/post/417.html1>路由+路由命名 - as2>路由分组+路由命名 - 'as' => 'admin::' + 'as' => 'dashboard' ---> route('admin::dashboard')3>路由分组:middleware - 中间件namespace - 命名空间domain - 子域名prefix - 路由前缀3.CSRF攻击 - http://laravelacademy.org/post/525.html表单 - 普通tokenajax - X-CSRF-Tokencookie - X-XSRF-Token从CSRF保护中排除指定URL - VerifyCsrfToken->except 中间件4.路由模型绑定Laravel 会自动解析定义在路由或控制器动作(变量名匹配路由片段)中的 Eloquent 模型类型声明Route::get('api/users/{user}', function (App\User $user) {// $user - 数据库查询到的用户信息(Eloquent模型类的实例化)    return $user->email;});5.表单方法伪造表单不支持put、patch、delete方法,添加隐藏字段 _method6.中间件 - http://laravelacademy.org/post/2803.html理解中间件的最好方式就是将中间件看做 HTTP 请求到达目标动作之前必须经过的“层”,每一层都会检查请求并且可以完全拒绝它。目录:app/Http/Middleware定义中间件:php artisan make:middleware OldMiddleware中间件前:1>如果我们想在请求处理前执行业务逻辑,则在$next闭包执行前执行业务逻辑操作:class BeforeMiddleware{    public function handle($request, Closure $next)    {        // 执行业务逻辑操作// 1.先执行我们自定义逻辑        return $next($request); // 2.后执行$next()    }}中间件后:1>如果想要在请求处理后执行中间件业务逻辑,则在$next闭包执行后执行操作:class AfterMiddleware{    public function handle($request, Closure $next)    {        $response = $next($request); // 1.先$next()        // 执行动作// 2.执行我们自定义逻辑        return $response;// 3.返回$next()之前的结果    }}我们处理的大部分操作都是第一种场景,即在请求处理前执行操作,比如用户认证、CSRF验证、维护模式等都是这样,但也有用到第二种场景的时候,比如StartSession中间件,该中间件在请求处理前后都有操作注册中间件 - app/Http/Kernel.php:全局中间件:想要中间件在每一个HTTP请求期间被执行,设置 $middleware(1) 数组即可分配中间件到路由:protected $routeMiddleware(2) = [    'auth' => \App\Http\Middleware\Authenticate::class,    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,];添加到该数组的元素,就可在路由选项数组中,调用Route::get('admin/profile', ['middleware' => 'auth', function () {    //}]);使用数组分配多个中间件到路由:Route::get('/', ['middleware' => ['first', 'second'], function () {    //}]);除了使用数组外,还可以使用 middleware 方法链的方式定义路由:Route::get('/', function () {    //})->middleware(['first', 'second']);中间件组:protected $middlewareGroups(3) = [    'web' => [        \App\Http\Middleware\EncryptCookies::class,        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,        \Illuminate\Session\Middleware\StartSession::class,        \Illuminate\View\Middleware\ShareErrorsFromSession::class,        \App\Http\Middleware\VerifyCsrfToken::class,    ],    'api' => [        'throttle:60,1',        'auth:api',    ],];中间件组可以被分配给路由和控制器动作,使用和单个中间件分配同样的语法。再次申明,中间件组的目的只是让一次分配给路由多个中间件的实现更加简单:Route::group(['middleware' => ['web']], function () {    //});中间件参数:class RoleMiddleware{    public function handle($request, Closure $next, $role) - 该中间件,需要一个$role参数    {        if (! $request->user()->hasRole($role)) {            // Redirect...        }        return $next($request);    }}中间件参数可以在定义路由时通过:分隔中间件名和参数名来指定,多个中间件参数可以通过逗号分隔:Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) {// role-中间件 & editor-参数值    //}]);可终止的中间件:中间件可能需要在 HTTP 响应发送到浏览器之后做一些工作!例如:Laravel 内置的“session”中间件会在响应发送到浏览器之后将 Session 数据写到存储器中,为了实现这个,定义一个可终止的中间件并添加 terminate 方法到这个中间件:class StartSession{    public function handle($request, Closure $next)    {        return $next($request);    }    public function terminate($request, $response)// 终止中间件,需要添加 'terminate()',看到没,可以接收 $response 参数了 --- 表示请求已经发送到了浏览器,浏览器的响应结果!    {        // 存储session数据...    }}这个东西,得解释下,看了好几遍才理解了意思:1.中间件的定义是:HTTP请求到达目标页面,添加的一些约束层。所以,中间件都具有 $request,而不可能出现 $response 响应2.终止中间件,添加了 terminate() 方法,它就可以接收 $response 响应了。它是在请求已到达了目标后的响应结果3.一旦你定义了一个可终止的中间件,应该将其加入到 HTTP kernel 的全局中间件列表中 ------- 就是kernel.php中的$middleware数组4.当调用中间件上的 terminate 方法时,Laravel 将会从服务容器中取出该 '中间件的新的实例'(新实例化的中间件对象)。并不是之前的 '中间件实例化对象'如果你想要在调用 handle 和 terminate 方法时使用同一个中间件实例,则需要使用容器的 singleton 方法将该中间件注册到容器中。因为http请求执行过程,肯定是:先执行了 handle(),然后等请求完毕后,再执行 $terminate(),会实例化同一个中间件的2个不同的对象。如果想保持同一个对象,就得采用 '单例模式' - 即文档中说的 'singleton()'7.控制器 - http://laravelacademy.org/post/2816.html & 1>简介:将所有的请求处理逻辑都放在 route.php 中是不合理的! ------- route.php是定义路由的,这个我们都清楚!记得路由中是支持 function(){} 匿名函数的,这里面就是匹配的路由,对应的请求逻辑!(所以,route.php 也是可以进行逻辑代码的)需要使用controller来管理逻辑,放在 'app/Http/Controllers/' 下,在route.php中,通过 controller@action 来定位哪个逻辑2>基本控制器:class UserController extends Controller{    public function showProfile($id)    {        return view('user.profile', ['user' => User::findOrFail($id)]);    }}Route::get('user/{id}', 'UserController@showProfile');// 请求控制器3>控制器&命名空间1.定义控制器路由时,并未指定完整的 '控制器命名空间',只定义了 'App\Http\Controllers' 之后的 'UserController'。默认情况下: RouteServiceProvider,中定义了一个 $namespace = 'App\Http\Controllers',我们相对它既可!2.如果控制器目录下,使用了多层目录,例如 'App\Http\Controllers\Photos\AdminController',路由调用:Route::get('foo', 'Photos\AdminController@method');4>控制器路由,也可以命名(别名)Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);// 使用as命名一个简单的名字,重定向&跳转更简单$url = route('name');// 生成url更加简单5>控制器中间件:1)传统的方式,同匿名函数路由一样Route::get('profile', [    'middleware' => 'auth',// 定义中间件,传统的方式    'uses' => 'UserController@showProfile']);2)将中间件放在 '控制器构造函数' 中,更加方便、灵活。构造函数中使用 middleware() 方法:class UserController extends Controller{    public function __construct()    {        $this->middleware('auth');// 一般的中间件        $this->middleware('log', ['only' => ['fooAction', 'barAction']]); // 中间件只能作用于控制器的这些方法        $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]); // 中间件作用于除了这些方法的其它方法    }}6>RESTful资源控制器 - 可了解RESTful,就是所有url都真对的是一个资源处理(百度、google,我也忘记了...)1)生成php artisan make:controller PhotoController // 一般的控制器的创建php artisan make:controller PhotoController --resource // RESTful风格的controller的创建默认会添加一系列的方法:index, create, store, show, edit, update, destroy我们可真对这个RESTful资源的一些列方法,进行路由:Route::resource('photo', 'PhotoController'); // 使用resource()方法,而非之前的get(),一个一个来设置(因为它们的标准是同一的)2)只定义部分资源路由Route::resource('photo', 'PhotoController', ['only' => ['index', 'show']]);// 指定哪些可用Route::resource('photo', 'PhotoController', ['except' => ['create', 'store', 'update', 'destroy']]);// 排除哪些可用3)重命名资源路由Route::resource('photo', 'PhotoController', ['names' => ['create' => 'photo.build']]);// 将create重命名为build4)觉得默认的RESTful方法,不够用,我们可以给controller添加更多的方法:Route::get('photos/popular', 'PhotoController@method');// 如果有必要在默认资源路由之外添加额外的路由到资源控制器,应该在调用 Route::resource 之前定义这些路由Route::resource('photos', 'PhotoController');7>依赖注入&控制器Laravel 使用服务容器解析所有的 Laravel 控制器,因此,可以在控制器的构造函数中类型声明任何依赖,这些依赖会被自动解析并注入到控制器实例中1)构造函数注入:use App\Repositories\UserRepository;// 引入依赖类class UserController extends Controller{    protected $users;    public function __construct(UserRepository $users)// 将依赖注入到构造方法    {        $this->users = $users;    }}2)除了构造函数注入之外,还可以在控制器的动作方法中进行依赖的类型提示use Illuminate\Http\Request;// 引入依赖类class UserController extends Controller{    public function store(Request $request) // 将依赖注入到普通的方法    {        $name = $request->input('name');        //    }}3)方法中,需要传递其它参数,参数在其它依赖之后:Route::put('user/{id}', 'UserController@update');// 需要一个参数use Illuminate\Http\Request;// 引入依赖类class UserController extends Controller{    public function store(Request $request, $id) // 将依赖注入到普通的方法,$id参数在$request参数之后    {        $name = $request->input('name');        //    }}8>路由缓存:1)注意:路由缓存不会作用于基于闭包的路由。要使用路由缓存,必须将闭包路由转化为控制器路由。2)命令:php artisan route:cache// 生成缓存php artisan route:clear// 清除缓存一旦,生成缓存,app/Http/routes.php将不在有效,使用缓存!一旦修改了routes.php,应该重新生成缓存

0 0
原创粉丝点击