如何实现一个php框架系列文章【4】url路由管理
我们支持3种路由模式
普通模式
_a=$app, _u=$ctl.$act
最简单的方式,专注实现业务$act函数,不需要再写额外代码
为什么参数名前面要加下划线就不解释了
easy模式
_easy=$app.$tpl.$ctl.$act
_easy=$app.$ctl.$act
在web开发中,通常我们在$act中输出一个前端页面,
easy模式下,如果未实现$act处理函数,会自动寻找并显示对应的前端模板文件。
对于简单的展示页面适合使用这种路由模式
url重写模式(需要nginx或apache配置)
apache: ^rewrite[\.\/](.*)$ /index.php?_rewrite=$1 [R,QSA]
nginx: rewrite ^/rewrite[\.\/](.*)$ /index.php?_rewrite=$1 last;
rewrite.{$app}.{$ctl}.{$act}.{$params}.html
或更加优雅的目录式访问方式
rewrite/{$app}/{$ctl}/{$act}/{$params}.html
其中$params为选填参数部分.格式为urlencode后的参数列表
如果想传递sp_uid=1&d=1.2&p=sb, 那么$params = sp_uid%3D1%26d%3D1.2%26p%3Ds%2Fb
或sp_uid/1/d/1.2/p/sb
在某些要求url中不能带?&特殊字符的场景下可以使用这种模式
1. 为了能通过qq oauth2登陆验证,需要配置重写规则
rewrite.thirdlogin.index.qqcallback.sp_uid%3D1.php
2. 资源静态化
rewrite.upload.index.out.uidm%3D310ef4b.png
3. 支付回调
rewrite.pay.weixin.native2_notify.php
4. 微信开放平台授权回调
rewrite/web/component/message/_app_id/xxxxxxx.php
部分实现代码
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$a = (! empty ( $_REQUEST [ '_a' ]) && is_string ( $_REQUEST [ '_a' ])) ? $_REQUEST [ '_a' ] : 'web' ; if (!preg_match( '/^[\w\.]+$/' , $a )) { exit ( 'invalid _app name! ' . htmlspecialchars( $a )); } $GLOBALS [ '_UCT' ][ 'APP' ] = ! empty ( $a ) ? strtolower ( $a ) : 'web' ; $u = (! empty ( $_REQUEST [ '_u' ]) && is_string ( $_REQUEST [ '_u' ])) ? $_REQUEST [ '_u' ] : 'index.index' ; if (!preg_match( '/^[\w\.]+$/' , $u )) { exit ( 'invalid _url name! ' . htmlspecialchars( $u )); } $u = explode ( '.' , $u , 2); $GLOBALS [ '_UCT' ][ 'CTL' ] = ! empty ( $u [ '0' ]) ? strtolower ( $u [ '0' ]) : 'index' ; $GLOBALS [ '_UCT' ][ 'ACT' ] = ! empty ( $u [ '1' ]) ? strtolower ( $u [ '1' ]) : 'index' ; |
easy模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
//easy 模式直接访问模板tpl if (! empty ( $_REQUEST [ '_easy' ]) && is_string ( $_REQUEST [ '_easy' ])) { $easy = explode ( '.' , $_REQUEST [ '_easy' ]); switch ( count ( $easy )) { case 4: $_GET [ '_u' ] = $_REQUEST [ '_u' ] = $easy [2] . '.' . $easy [3]; if (preg_match( '/^[\w\.]+$/' , $easy [1])) { $GLOBALS [ '_UCT' ][ 'TPL' ] = $easy [1]; } $_GET [ '_a' ] = $_REQUEST [ '_a' ] = $easy [0]; break ; case 3: $_GET [ '_u' ] = $_REQUEST [ '_u' ] = $easy [1] . '.' . $easy [2]; $_GET [ '_a' ] = $_REQUEST [ '_a' ] = $easy [0]; break ; case 2: $_GET [ '_u' ] = $_REQUEST [ '_u' ] = $easy [1]; $_GET [ '_a' ] = $_REQUEST [ '_a' ] = $easy [0]; break ; case 1: $_GET [ '_a' ] = $_REQUEST [ '_a' ] = $easy [0]; break ; default : exit ( 'invalid _easy param! ' . htmlspecialchars( $_REQUEST [ '_easy' ])); } } |
rewrite模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
//url重写模式 if (! empty ( $_REQUEST [ '_rewrite' ]) && is_string ( $_REQUEST [ '_rewrite' ])) { //1.支持apache 重写模式下?后的参数缺失的情况 if ( stripos ( $_SERVER [ 'SERVER_SOFTWARE' ], 'nginx' ) === false) { $_REQUEST [ '_rewrite' ] = urldecode( substr ( $_SERVER [ 'QUERY_STRING' ], strlen ( '_rewrite=' ))); } //2. 丢弃_rewrite中的后缀名 $rewrite = substr ( $_REQUEST [ '_rewrite' ], 0, strrpos ( $_REQUEST [ '_rewrite' ], '.' )); //3. 支持/作为分隔符 $sp = '.' ; for ( $i = 0; $i < strlen ( $rewrite ); $i ++) { if (in_array( $rewrite [ $i ], array ( '.' , '/' ))) { $sp = $rewrite [ $i ]; break ; } } $rewrite = explode ( $sp , $rewrite , 4); //最后1段是必填后缀名 switch ( count ( $rewrite )) { case 3: case 4: { $_GET [ '_a' ] = $_REQUEST [ '_a' ] = $rewrite [0]; $_GET [ '_u' ] = $_REQUEST [ '_u' ] = $rewrite [1]. '.' . $rewrite [2]; if (! empty ( $rewrite [3])) { if ( strpos ( $rewrite [3], '/' )) { $params = explode ( '/' , $rewrite [3]); for ( $i =0; $i +1< count ( $params ); $i +=2) { $_REQUEST [urldecode( $params [ $i ])] = urldecode( $params [ $i +1]); } } else { foreach ( explode ( '&' , $rewrite [3]) as $p ) { list( $k , $v ) = explode ( '=' , $p , 2); $_REQUEST [urldecode( $k )] = urldecode( $v ); } } } break ; } case 2: $_GET [ '_a' ] = $_REQUEST [ '_a' ] = $rewrite [0]; $_GET [ '_u' ] = $_REQUEST [ '_u' ] = $rewrite [1]; break ; case 1: $_GET [ '_a' ] = $_REQUEST [ '_a' ] = $rewrite [0]; break ; default : break ; } } |
如何实现一个php框架系列文章【4】url路由管理的更多相关文章
- 如何实现一个php框架系列文章【开篇】
1.本系列文章的目的 实现一个小而美的产品级别php框架 自己动手实现一个新框架仅用于学习交流,不打算替代市面上现有的其他主流框架. 2. 我要一个怎样的PHP框架 简单实用,安全优雅,博采众长 安装 ...
- 如何实现一个php框架系列文章【5】安全处理输入
所有的外部输入参数都应该检查合法性. 未正确处理输入数据将可能导致sql注入等漏洞. 框架提供系列函数来取$_REQUEST中的值 requestInt requestString requestFl ...
- 如何实现一个php框架系列文章【1】如何组织文件
1. 组织文件布局应该考虑什么问题 前后端分离 各业务模块分离但方便互相调用 上传文件安全性 方便接入第三方类库 如图所示 框架入口文件 uct/index.php 框架目录 uct/ ...
- 如何实现一个php框架系列文章【6】mysql数据库
实现一个mysql数据库封装需要考虑的问题 使用方便性 采用直接sql语句操作方式.只要会写sql语句,那么将没有其他学习成本. uctphp框架提供的dba辅助封装类,用会之后将爱不释手. 使用前需 ...
- 如何实现一个php框架系列文章【2】实现类的自动加载
根据前一篇文章的设计原则,我们暂时把php文件分为3类,类名和文件名都遵守如下约定. 类名 文件名 路径 模型类m {$app}Mod {$app}.mod.php {$app}/model ...
- 如何实现一个php框架系列文章【3】支持psr4的自动加载类
psr4自动加载规范https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-4-autoloader-cn.md 我们把第三方使用psr规范的类库放在v ...
- 2019 年起如何开始学习 ABP 框架系列文章-开篇有益
2019 年起如何开始学习 ABP 框架系列文章-开篇有益 [[TOC]] 本系列文章推荐阅读地址为:52ABP 开发文档 https://www.52abp.com/Wiki/52abp/lates ...
- Artech的MVC4框架学习——第二章URL路由
总结:HttpModule 和HttpHandler是Asp.net管道的两个重要组件.请求最终处理通过HttpHandler完成.MVC就是通过名为MvcHandler自定义HttpHandler现 ...
- 【开源】EFW框架系列文章索引
开源轻量级.Net框架EnterpriseFrameWork详解 ——自己动手写框架 ——适合中小企业的开发框架 ——Ajax+JqueryEasyUI+NotNetBar+MVC+WebServic ...
随机推荐
- javascript动画系列第二篇——磁性吸附
× 目录 [1]范围限定 [2]拖拽范围 [3]磁性吸附 前面的话 上一篇,我们介绍了元素拖拽的实现.但在实际应用中,常常需要为拖拽的元素限定范围.而通过限定范围,再增加一些辅助的措施,就可以实现磁性 ...
- dotNet Core开发环境搭建及简要说明
一.安装 .NET Core SDK 在 Windows 上使用 .NET Core 的最佳途径:使用Visual Studio. 免费下载地址: Visual Studio Community 20 ...
- springmvc 多数据源 SSM java redis shiro ehcache 头像裁剪
获取下载地址 QQ 313596790 A 调用摄像头拍照,自定义裁剪编辑头像 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单; 技术:31359679 ...
- 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1
HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...
- iOS开源项目周报1215
由OpenDigg 出品的iOS开源项目周报第一期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. PY ...
- iOS--->微信支付小结
iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...
- MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义
[转自网络]https://my.oschina.net/cers/blog/292191 PK Belongs to primary key 作为主键 NN Not Null 非空 UQ Uniqu ...
- OpenGL shader 中关于顶点坐标值的思考
今天工作中需要做一个事情: 在shader内部做一些空间距离上的计算,而且需要对所有的点进行计算,符合条件的显示,不符合条件的点不显示. 思路很简单,在vertex shader内知道顶点坐标,进行计 ...
- 如何让我们的PHP在Jexus中跑起来
最近一段时间,经常看到不少的朋友在问,应该怎么设置才能够让Jexus支持PHP.其实,Jexus在很早之前就已经是可以支持PHP,像Apache或Nginx一样充当PHP的Web服务器的.不过由于没有 ...
- Integer.parseInt 引发的血案
Integer.parseInt 处理一个空字符串, 结果出错了, 程序没有注意到,搞了很久, 引发了血案啊!! 最后,终于 观察到了, 最后的部分: Caused by: java.lang.NoC ...