-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRoute.php
More file actions
126 lines (112 loc) · 4 KB
/
Route.php
File metadata and controls
126 lines (112 loc) · 4 KB
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?php
abstract class RouterAbstract {
public abstract function getRoute($request);
}
/**
* 路由器
*/
class Router extends RouterAbstract{
//+?的意思匹配一次或多次,但尽量少重复 abcabc 只会获取abc
const REGEX_ANY = "([^/]+?)";
const REGEX_INT = "([0-9]+?)";
const REGEX_ALPHA = "([a-zA-Z_-]+?)";
const REGEX_ALPHANUMERIC = "([0-9a-zA-Z_-]+?)";
const REGEX_STATIC = "%s";
protected $routes = array();
protected $baseUrl = '';
//设定基本的url
public function setBaseUrl($baseUrl)
{
$this->baseUrl = preg_quote($baseUrl,'@');
}
//添加路由
public function addRoute($route,$option=array())
{
$this->routes[] = array('pattern'=>$this->_parseRoute($route),
'option'=>$option);
}
//解析路由的正则表达式
private function _parseRoute($route)
{
$baseUrl = $this->baseUrl;
if ($route == '/') {
//如果是根目录则直接返回
return "@^$baseUrl/$@";
}
//分割
$parts = explode("/", $route);
$regex = "@^$baseUrl";
if ($route[0] == "/") {
//如果字符串的第一值是'/',则扔掉
array_shift($parts);
}
foreach ($parts as $part) {
$regex .= "/";
$args = explode(":", $part);
if (sizeof($args) == 1) {
//如果只有一个值参数则为自定义正则表达式,preg_quote转码
$regex .= sprintf(self::REGEX_STATIC,
preg_quote(array_shift($args),'@'));
continue;
} elseif ($args[0] == '') {
//如果第一个只为空,扔掉,类型设置为false,表示没有类型
array_shift($args);
$type = false;
} else {
//第一个值为类型
$type = array_shift($args);
}
//获得对应正则值
$key = array_shift($args);
if ($type == "regex") {
$regex .= $key;
continue;
}
//去除不符合的字符
$this->normalize($key);
//给匹配结果命名
$regex .= '(?P<'.$key.'>';
switch (strtolower($type)) {
case 'int':
case 'integer':
$regex .= self::REGEX_INT;
break;
case 'alpha':
$regex .= self::REGEX_ALPHA;
break;
case 'alphanumeric':
case 'alphanum':
case 'alnum':
$regex .= self::REGEX_ALPHANUMERIC;
break;
default:
$regex .= self::REGEX_ANY;
break;
}
$regex .= ")";
}
$regex .= '$@u';
return $regex;
}
public function getRoute($request)
{
$matches = array();
foreach ($this->routes as $route) {
if (preg_match($route['pattern'],$request,$matches)) {
//获得匹配结果,如果key为int型,数据则不能用
foreach ($matches as $key => $value) {
if (is_int($key)) {
unset($matches[$key]);
}
}
$result = $matches + $route['option'];
return $result;
}
}
}
public function normalize(&$param)
{
$param = preg_replace("/[^0-9a-zA-Z]/", "", $param);
}
}
?>