我們支持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
;
}
}