You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
5.1 KiB

3 years ago
<?php
/**
* 路由类
*/
namespace base;
class Route {
/**
* 路由规则
* @var array
*/
static protected $rewriteRule = array();
/**
* 路由开关
* @var boolean
*/
static protected $rewriteOn = false;
/**
* 解析URL
* @param array $rewriteRule 路由规则
* @param boolean $rewriteOn 路由开关
* @return void
*/
static public function parseUrl( $rewriteRule, $rewriteOn=false) {
self::$rewriteRule = $rewriteRule;
self::$rewriteOn = $rewriteOn;
if( self::$rewriteOn && !empty(self::$rewriteRule ) ) {
if( ($pos = strpos( $_SERVER['REQUEST_URI'], '?' )) !== false ){
parse_str( substr( $_SERVER['REQUEST_URI'], $pos + 1 ), $_GET );
}
foreach(self::$rewriteRule as $rule => $mapper) {
$rule = ltrim($rule, "./\\");
if( false === stripos($rule, 'http://')){
$rule = $_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER["SCRIPT_NAME"]), '/\\') . '/' . $rule;
}
$rule = '/'.str_ireplace(array('\\\\', 'http://', '-', '/', '<', '>', '.'), array('', '', '\-', '\/', '(?<', ">[a-z0-9_%]+)", '\.'), $rule).'/i';
if( preg_match($rule, $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], $matches) ){
foreach($matches as $matchkey => $matchval){
if(('app' === $matchkey)){
$mapper = str_ireplace('<app>', $matchval, $mapper);
}else if('c' === $matchkey){
$mapper = str_ireplace('<c>', $matchval, $mapper);
}else if('a' === $matchkey){
$mapper = str_ireplace('<a>', $matchval, $mapper);
} else {
if( !is_int($matchkey) ) $_GET[$matchkey] = $matchval;
}
}
$_REQUEST['r'] = $mapper;
break;
}
}
}
$routeArr = isset($_REQUEST['r']) ? explode("/", $_REQUEST['r']) : array();
$app_name = empty($routeArr[0]) ? Config::get('DEFAULT_APP') : $routeArr[0];
$controller_name = empty($routeArr[1]) ? Config::get('DEFAULT_CONTROLLER') : $routeArr[1];
$action_name = empty($routeArr[2]) ? Config::get('DEFAULT_ACTION') : $routeArr[2];
$_REQUEST['r'] = $app_name .'/'. $controller_name .'/'. $action_name;
if(strpos($action_name, '_')){
$action_name = str_replace('_', ' ', $action_name);
$action_name = ucwords(strtolower($action_name));
$action_name = str_replace(' ', '', $action_name);
}
if( !defined('APP_NAME') ) define('APP_NAME', strtolower($app_name));
if( !defined('CONTROLLER_NAME') ) define('CONTROLLER_NAME', $controller_name);
if( !defined('ACTION_NAME') ) define('ACTION_NAME', $action_name);
}
/**
* 生成URL
* @param string $route URL路径
* @param array $params URL参数
* @return string
*/
static public function url($route=null, $params=array()) {
$app = APP_NAME;
$controller = CONTROLLER_NAME;
$action = ACTION_NAME;
if($route){
$route = explode('/', $route, 3);
$routeNum = count($route);
switch ($routeNum) {
case 1:
$action = $route[0];
break;
case 2:
$controller = $route[0];
$action = $route[1];
break;
case 3:
$app = $route[0];
$controller = $route[1];
$action = $route[2];
break;
}
}
$default_controller = strtolower(Config::get('DEFAULT_CONTROLLER'));
$default_action = Config::get('DEFAULT_ACTION');
$route = $app;
$route .= ($default_controller != $controller || $default_action != $action) ? '/'.$controller : '';
$route .= ($default_action != $action) ? '/'.$action : '';
$paramStr = empty($params) ? '' : '&' . http_build_query($params);
$url = $_SERVER["SCRIPT_NAME"] . '?r=' . $route . $paramStr;
if( self::$rewriteOn && !empty(self::$rewriteRule ) ) {
static $urlArray = array();
if( !isset($urlArray[$url]) ){
foreach(self::$rewriteRule as $rule => $mapper){
$mapper = '/'.str_ireplace(array('/', '<app>', '<c>', '<a>'), array('\/', '(?<app>\w+)', '(?<c>\w+)', '(?<a>\w+)'), $mapper).'/i';
if( preg_match($mapper, $route, $matches) ){
list($app, $controller, $action) = explode('/', $route);
$urlArray[$url] = str_ireplace(array('<app>', '<c>', '<a>'), array($app, $controller, $action), $rule);
if( !empty($params) ){
$_args = array();
foreach($params as $argkey => $arg){
$count = 0;
$urlArray[$url] = str_ireplace('<'.$argkey.'>', $arg, $urlArray[$url], $count);
if(!$count) $_args[$argkey] = $arg;
}
if( !empty($_args) ){
$urlArray[$url] = preg_replace('/<\w+>/', '', $urlArray[$url]). '?' . http_build_query($_args);
}
}
if(false === stripos($urlArray[$url], 'http://')){
$urlArray[$url] = 'http://'.$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER["SCRIPT_NAME"]), "./\\") .'/'.ltrim($urlArray[$url], "./\\");
}
$rule = str_ireplace(array('<app>', '<c>', '<a>'), '', $rule);
if( count($params) == preg_match_all('/<\w+>/is', $rule, $_match)){
return $urlArray[$url];
}
}
}
return isset($urlArray[$url]) ? $urlArray[$url] : $url;
}
return $urlArray[$url];
}
return $url;
}
3 years ago
}