php 各种路由分析_PHP解析PATH_INFO模式URL的路由类

编码工作中框架给我们提供了很多便利,自己更多处理的是业务层的代码,而很少接触较为基础的东西。

趁最近有空,自己想着写了一个处理PATH_INFO模式URL的路由类。因为自己工作常用框架是TP5,所以有些风格习惯定义和TP5很像。

完整DEMO请参阅我的码云:https://gitee.com/VwenX/Router

下面是路由部分核心类,URL解析后用反射API处理参数然后调用对应方法。

// 定义常量

define('URL_PATH',isset($_SERVER['PATH_INFO']) ? preg_replace('/\/+/','/',strtolower($_SERVER['PATH_INFO'])) : '/');

define('APP_PATH', 'app');

define('Control_PATH', 'controller');

class Route

{

// 路由规则

private static $rules = [

'get' => [],

'post' => [],

'put' => [],

'delete' => [],

'*' => []

];

/**

* 绑定路由

* @param string $rule 路由规则

* @param string $route 路由地址

* @param string $type 请求类型

* By.Vwen https://gitee.com/VwenX/Router

*/

static function rule($rule, $route = '', $type = '*')

{

$rule = strtolower($rule);

$rule = '/'==substr($rule,0,1) ? $rule : '/'.$rule;

$route = strtolower($route);

$type = strtolower($type);

if ('*' == $type) {

foreach (self::$rules as $key => $value) {

self::$rules[$key][$rule] = $route;

}

}else{

self::$rules[$type][$rule] = $route;

self::$rules['*'][$rule] = $route;

}

}

/**

* 提供快捷绑定

* 如 Route::get() Route::post()

* 仅为概念简写,实际应用请按需修改及验证

*/

static function __callStatic($func, $arguments)

{

$arguments[] = $func;

self::rule(...$arguments);

}

/**

* 解析当前请求URL

* @return array 路由信息数组

*/

static function parseUrl()

{

$analysis = ['status'=>404];

$METHOD = strtolower($_SERVER['REQUEST_METHOD']);

// 直接匹配

if (isset(self::$rules[$METHOD][URL_PATH])) {

$analysis['status'] = 200;

$analysis['rule'] = URL_PATH;

$analysis['route'] = self::$rules[$METHOD][URL_PATH];

}else{

// 列表匹配

foreach (self::$rules[$METHOD] as $rule => $route) {

if (substr($rule,-1)=='$' && substr_count($rule,'/')!=substr_count(URL_PATH,'/')) {

continue ;

}

$reg = '/^'.str_replace('/','\/',preg_replace('/:[a-z]+(?=\/|\$|$)/','\S+',$rule)).'/';

if (!preg_match($reg,URL_PATH)) {

continue ;

}

$analysis['status'] = 200;

$analysis['rule'] = $rule;

$analysis['route'] = $route;

break;

}

}

// 处理未注册的路由 /M/C/A

if (!isset($analysis['route'])) {

$path_list = explode('/', trim( URL_PATH,'/'));

$module = isset($path_list[0]) ? $path_list[0] : 'index';

$Controller = isset($path_list[1]) ? $path_list[1] : 'index';

$action = isset($path_list[2]) ? $path_list[2] : 'index';

$analysis['rule'] = $analysis['route'] = '/'.$module.'/'.$Controller.'/'.$action;

}

// 获取路由参数

if (isset($analysis['route'])) {

$param = [];

$rule_list = explode('/', $analysis['rule']);

$path_list = explode('/', URL_PATH);

if(strpos($analysis['rule'], ':')!==false){

foreach ($rule_list as $key => $value) {

if (substr($value,0,1)==':') {

$param[trim($value,':$')] = $path_list[$key];

}

}

}

// 获取剩余参数

for ($i=count($rule_list); $i < count($path_list); $i+=2) {

if (isset($path_list[$i+1])) {

$param[$path_list[$i]] = $path_list[$i+1];

}

}

$analysis['param'] = self::Params($param);

// 在控制器方法传参中用 $req 获取请求参数

$analysis['param']['req'] = $analysis['param'];

}

return $analysis;

}

/**

* 处理请求参数

* @param array $param PATH_INFO参数

* @return array

*/

static function Params($param=[])

{

return array_merge($param,$_GET,$_POST);

}

/**

* 生成URL

* @param string $route 路由地址 模块/控制器/方法

* @param array $vars 参数数组

* @param string $method 按特定请求模式解析

* @return string 处理好的URL

*/

static function getUrl($route='',$vars=[],$method='*')

{

$route = strtolower(trim($route,'/'));

$method = strtolower($method);

$rule = array_search($route,self::$rules[$method]);

if (!$rule) {

return '';

}

$rule_list = explode('/', trim($rule,'/'));

// 处理预定义参数

if (strpos($rule, ':')!==false) {

foreach ($rule_list as $key => $value) {

if (strpos($value, ':')!==false) {

$rule_list[$key] = isset($vars[trim($value,':$')]) ? $vars[trim($value,':$')] : '';

if (isset($vars[trim($value,':$')])) unset($vars[trim($value,':$')]);

}

}

}

// 处理剩余参数

if (strpos($rule, '$')==false && $vars != '') {

foreach ($vars as $key => $value) {

$rule_list[] = $key;

$rule_list[] = $value;

}

}

$rule = rtrim('/'.implode('/',$rule_list),'$');

return $rule;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值