如何实现一个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 ...
随机推荐
- C#使用GET、POST请求获取结果
C#使用GET.POST请求获取结果,这里以一个简单的用户登陆为例. 1. 使用GET请求获取结果 1.1 创建LoginHandler.aspx处理页面 protected void Page_Lo ...
- RMS Server打开或关闭日志记录
原文: https://technet.microsoft.com/zh-cn/library/cc732758 在 Active Directory Rights Management Servic ...
- Activity之概览屏幕(Overview Screen)
概览屏幕 概览屏幕(也称为最新动态屏幕.最近任务列表或最近使用的应用)是一个系统级别 UI,其中列出了最近访问过的 Activity 和任务. 用户可以浏览该列表并选择要恢复的任务,也可以通过滑动清除 ...
- 图解Spark API
初识spark,需要对其API有熟悉的了解才能方便开发上层应用.本文用图形的方式直观表达相关API的工作特点,并提供了解新的API接口使用的方法.例子代码全部使用python实现. 1. 数据源准备 ...
- closure
什么是闭包?百度的答案: 闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)."闭包&quo ...
- mysql集群(双主)
0.安装 所谓双主基本可以理解为两台服务器互为主备,其核心思路与主备配置相同. 服务器A: 内网IP: 10.44.94.219 服务器B: 内网IP: 10.44.94.97 1.配置服务器A lo ...
- qt5中信号和槽的新语法
qt5中的连接 有下列几种方式可以连接到信号上 旧语法 qt5将继续支持旧的语法去连接,在QObject对象上定义信号和槽函数,及任何继承QObjec的对象(包含QWidget). connect(s ...
- ASP.NET Web API Model-ValueProvider
ASP.NET Web API Model-ValueProvider 前言 前面一篇讲解了Model元数据,Model元数据是在Model绑定中很重要的一部分,只是Model绑定中涉及的知识点比较多 ...
- ABP框架 - 依赖注入
文档目录 本节内容: 什么是依赖注入 传统方式的问题 解决方案 构造器注入模式 属性注入模式 依赖注入框架 ABP 依赖注入基础 注册依赖 约定注入 辅助接口 自定义/直接 注册 使用IocManag ...
- springmvc注解事例
注解有简化 ,灵活性增强的功能 1.引入jar包 com.springsource.javax.validation-1.0.0.GA.jarcom.springsource.org.aopallia ...