ThinkPHP6.0学习笔记

Wesley13
• 阅读 899

ThinkPHP-路由

by:Mirror王宇阳

Thinkphp的路由的主要作用是为了让URL地址更加美观、简洁、优雅……;设置路由对URL的检测、验证等操作提供了极大的便利性;路由功能是默认开启的config/app.php文件中设置:

'with_route'    =>    true;
  • 路由配置文件:config/route.php

  • 路由定义文件:route/app.php

route目录下的定义文件的文件名是随机的,都会有效。

路由定义

定义一次路由测试的文件:Address.php

class Address
{
    public function index()
    {
        return 'index';
    }
    public function details($id)
    {
        return 'details目前调用的ID'.$id;
    }
}
  • 未定义路由规则的情况下,默认的URL访问方法

    http://xxx.com/Index.php/address/id/5
    
  • 定义URL路由规则,在route/app.php定义文件中配置

    Route::rule('details/:id','Address/details')
    
    
    http://xxx.com/Index.php/details/5
    

    路由规则配置完成后,必须使用路由规则进行访问;否则视为非法请求


注册路由定义

Route::rule('路由表达式','路由地址','请求类型')

路由表达式:泛指路由访问规则

路由地址:泛指访问目标的地址(控制器/方法/参数)

请求类型:默认 -> any

类型

描述

快捷方法

GET

GET请求

get

POST

POST请求

post

PUT

PUT请求

put

DELETE

DELETE请求

delete

PATCH

PATCH请求

patch

*

任何请求类型

any

快捷注册路由定义

Route::[快捷方法名]('路由表达式','路由地址')

示例:

Route::rule('details/:id','Address/details')
    
URL:http://xxx.com/Index.php/details/5

注册rule路由到Address控制器的details

强制路由:设置开启了强制路由,所有访问都会要求按照路由访问规则进行,否则报错;

// 是否强制使用路由
'url_route_must'        => true,

首页路由配置:(反斜杠就是首页地址)

Route::rule('/','Index/index');

闭包支持

闭包支持我们直接通过URL执行,而不需要通过控制器方法:

Route::get('think', function () {
    return 'hello,ThinkPHP6!';
});


Route::get('think', function ($id) {
    return 'hello!'.$id;
});

路由规则表达式

规则表达式通常包含静态规则动态规则,以及两种规则的结合,例如下面都属于有效的规则表达式:

// 静态路由
Route::rule('ads','Address/index');
[URL]=> tp/Index.php/ads


// 静态+动态路由
Route::rule('datails/:id','Address/details');
[URL]=> tp/Index.php/details


// (多参数)静态+动态路由
Route::rule('search/:id/:uid','Address/search');
[URL]=> tp/Index.php/search/1/1


// 全动态地址 不会限制search参数固定
Route::rule(':search/:id/:uid','Address/search');
[URL]=> tp/Index.php/search/1/1
[URL]=> tp/Index.php/s/1/1


// 可选参数地址
Route::rule('blog/:year/[:month]','Address/blog');


// 完全匹配地址
Route::rule('search/:id/:uid$','Address/search');
[URL]=> tp/Index.php/search/1/1
    
//在路由配置文件中可以开启全局路由完全匹配
//开启完全匹配后,使用`completeMatch(false)`关闭


// 额外参数 (隐式传值)
// 路由跳转支持传入不显示在URL中参数
Route::rule('blog/:id','blog/read')
    ->append(['status'=>1,'app_id'=>5]);

路由标识

根据路由生成URL地址,定义路由的时候指定生成唯一性标识

// 定义标识
Route::rule('blog/:year/:month','Adderss/blog')
    ->name('route_blog');


return url('route_blog',
    ['year'=>$year,'month'=>$month]
);

变量规则

系统默认的路由变量规则是\w+ ;可以在路由配置文件中修改变量规则

使用pattern()方法,可以对参数变量进行规则设置:

Route::rule('details/:id','Address/details')
    ->pattern(['id'=>'\d+']);

pattern()接收数组传递,支持设置多个参数变量的规则

Route::pattern([
   'id'        =>    '\d+',
   'uid'    =>    '\d+'
]);

在路由定义文件中可以用上述方法定义全局规则

支持使用组合变量规则方式,实现路由规划:

Route::rule('details-<id>','Address/details')
    ->pattern('id','\d+');

动态组合拼装:

Route::rule('details-:name-:id','Hello:name/index')
    ->pattern('id','\d+')

路由地址

路由的地址一般为:控制器/操作方法

Route::rule('/','Index/index.php');

多级控制器,路由地址

Route::rule('details/:id','group.Blog/details');

完整路径的操作方法:完整类名@操作方法

静态方法的地址操作:完整类名::静态方法

路由使用::readirect()方法实现重定向跳转


路由参数

设置路由的时候,可以设置相关的方法进行,从而实施匹配检测和行为执行

参数

说明

方法名

ext

URL后缀检测,支持匹配多个后缀

ext

deny_ext

URL禁止后缀检测,支持匹配多个后缀

denyExt

https

检测是否https请求

https

domain

域名检测

domain

complete_match

是否完整匹配路由

completeMatch

model

绑定模型

model

cache

请求缓存

cache

ajax

Ajax检测

ajax

pjax

Pjax检测

pjax

json

JSON检测

json

validate

绑定验证器类进行数据验证

validate

append

追加额外的参数

append

middleware

注册路由中间件

middleware

filter

请求变量过滤

filter

ext方法是检测URL后缀

Route::rule('details/:id','Address/details')->ext('html');

https方法检测是否为https请求

Route::rule('details/:id','Address/details')
    ->https()
    ->ext('html');

如果你需要批量设置路由参数,也可以使用option方法。

Route::get('new/:id', 'News/read')
    ->option([
        'ext'   => 'html',
        'https' => true
    ]);

域名路由

限制在某域名下才解析路由

Route::domain('baidu.com',function(){
    Route::rule('blog/:id','Address/blog')
})

域名路由支持路由参数的操作

跨域请求

浏览器的安全机制会拦截非同源(跨域)的请求;在Thinkphp路由中,使用allowCrossDomain()来实现跨域请求,设置后该条路由就会允许非同源的请求:

Route::rule('details/:id'.'Address/details')
    ->allowCrossDomain();

同时为了安全考虑(不是什么人都可以来我这的)支持限制指定的跨站请求:

Route::rule('details/:id'.'Address/details')
    ->allowCrossDomain([
        'Access-Control-Allow-Origin' => "http://baidu.com"
    ]);

路由分组

路由分组,将相同前缀的路由合并分组,简化路由定义有利于匹配和维护;

使用group()进行分组路由注册:

Route::group('address',function(){
    Route::rule(':id','Address/details'),
    Route::rule(':name','Address/search');
})->pattern(['id'=>'\d+','name'=>'\w+']);

group()的第一参数可以省略,第一参数仅仅是给路由设置了一个公共路由设置参数,第一参数添加后就可以省略路由规则的内容,上述和下面两个程序对比就有效果;不过如果简写了规则名,就会发生访问冲突,这是就需要使用pattern() 限制每一参数的接收范围 不建议简写;个人更建议用下面的这种方法来分组。

Route::group('add',function(){
    Route::rule('de/:id','Address/details'),
    Route::rule('se/:name','Address/search');
});
[URL] => tp/Index.php/add/de/1

使用prefix()可以省略分组地址中的控制器

Route::group('add',function(){
    Route::rule('de/:id','details'),
    Route::rule('se/:name','search');
})->prefix('Address/');

路由规则在解析的时候会消耗较多的内存资源,尤其是路由规则特别庞大的时候;

这里可以开启延迟解析来节约内存空间(只有匹配到才执行路由)

MISS路由

全局MISS:类似开启强制路由功能,匹配不到相应规则自动跳到MISS;

Route::miss('public/miss');
// 闭包
Route::miss(function(){
    return '404 Not Found!';
});

局部/分组MISS:在分组中使用,不满足匹配规则调整到该分组

Route::group('add',function(){
    Route::rule('de/:id','details'),
    Route::rule('se/:name','search'),
    Route::miss('miss')
})->prefix('Address/');

域名MISS路由:支持该路由设置单独MISS路由

Route::domain('blog', function () {
    // 动态注册域名的路由规则
    Route::rule('new/:id', 'news/read');
    Route::rule(':user', 'user/info');
    Route::miss('blog/miss');
});

资源路由

资源路由:采用固定的常用方法实现简化URL的功能;

创建资源路由

Route::resource('[资源规则名]','[访问路径]');


class Address
{
    public function index()
    {
        return 'index';
    }
    public function details($id)
    {
        return 'details目前调用的ID=>'.$id;
    }
    public function search($name)
    {
        return "Name => ".$name;
    }
    public function blog($year,$month)
    {
        return url('route_blog',['year'=>$year,'month'=>$month]);
    }
}

创建Address的资源控制器后,在路由定义文件中注册资源路由

Route::resource('add','Address');

资源路由被被成功注册后就会自动完成方法匹配:

index ==> Address/index -> index

details ==> Address/details-> details/:id

search ==> Address/search -> search/:name

blog ==> Address/blog -> blog/:year/:month

vars()修改默认参数名称;参数默认采用$id名称

Route::resource('add','Address')
    ->vars(['add'=>'add_id']);

在控制器中也要相应的修改

only()限定系统提供的资源方法

Route::resource('add','Address')
    ->only(['index','search','blog']);

except()排除系统提供的资源方法

Route::resource('add','Address')
    ->except(['index']);

rest()更改系统的默认方法(请求方法、地址、操作)

Route::rest('create',['GET','/:id/add','add'])

嵌套资源路由

……

注解路由

路由的注解方式不是系统默认支持,需要安装扩展:

composer require tohthink/think-annotation

引入相关类库:use think\annotation\Route

完成简单的引入之后,在控制端设置注解代码即可,使用PHPDOC生成一段;然后添加路由规则;

/**
 * @parom $id
 * @return string
 * @route("details/:id");
 */

注解模式支持资源路由:

use think\annontation\Route\Resource;
/**
 * @Resource("blog")
 */

注解模式支持分组:

use think\annontation\route\Group;
/**
 * @Group('ads')
 */

URL生成

使用Route::buildUrl()获取路由的URL地址

Route::buildUrl('地址',[参数]……)


public function details($id)
{
    return Route::buildUrl('Url/details',['id'=>$id]);
}

如果给路由定义了一个别名,就可以在buildUrl()中使用;

同时可以使用助手函数url()来代替;

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
海军 海军
3年前
Vue | 路由守卫面试常考
前言最近在整理基础,欢迎一起交流学习<br/结尾有彩蛋哦!🎉🎉🎉VueRouter路由守卫导图目录1.路由守卫分类2.全局路由守卫3.单个路由守卫4.组件路由守卫5.路由守卫执行的完整过程<hr/路由守卫分类全局路由单个路由独享组件内部
Stella981 Stella981
3年前
Spring Cloud Gateway中的权重路由
摘要:本文主要通过运用SpringCloudGateway的WeightRoutePredicateFactory对URL进行权重路由。1.权重路由1.1权重路由使用场景在开发或者测试的时候,或者线上发布,线上服务多版本控制的时候,需要对服务提供权重路由,最常见的使用就是,一个服务有两个版本,旧版本V1,新版本
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Linux策略路由详解
概述在Linux中,我们通常使用route命令来做路由信息的管理。但是该命令仅仅只能用于基本路由信息的管理,面对功能更加强大的基于策略的路由机制,route命令就显得捉襟见肘。在传统路由算法中,只能基于目的地址进行路由选择。但是如果对
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这