时间:2021-07-01 10:21:17 帮助过:4人阅读
RewriteEngine On RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.+) index.php/$1 [L]
/** *路由配置文件编写说明: * 路由配置在一个array数组中,一条记录代表一个规则 * 其中数组key的数据代表匹配的路径格式:使用特定的字符串标识 如:'/{id}' * 字符串中可以包含特定的变量,所有变量使用大括号{}包裹起来 * 数组value里是一个array数组,是对key中路径中变量进行特定处理 * 变量写在数组的key中,规范写在数组的value里,如:array('id'=>'/\d+/','_m'=>'frontpage','_a'=>'index') * 规范分成两类: * 1.格式判断:比如 '/{id}'=> array('id'=>'/\d+/','_m'=>'frontpage','_a'=>'index') 为例,其中'id'=>'/\d+/'就是一个格式判断, * 表示id变量只能是数字,格式判断后面只能使用正则表达式,由于PHP没有正则类,所以我指定 '/XXX/'和'#XXX#'格式的字符串为正则表达式 * 2.默认参数:比如 '/{id}'=> array('id'=>'/\d+/','_m'=>'frontpage','_a'=>'index') 为例,其中'_m'=>'frontpage'就是一个默认参数, * 因为前面的路径没有_m和_a信息,所以后面会使用默认参数作为_m和_a的值 * * 所以对于规则'/{id}'=> array('id'=>'/\d+/','_m'=>'frontpage','_a'=>'index')。我传入 /3 系统会转换成 index.php?_m=frontpage&_a=index&id=3 * * 规则匹配是按照$routes数组的顺序逐一匹配,一旦匹配上了就不往下匹配了。所以一些特定的匹配规则要放在前面,通用的放在后面。 * 否则可能导致不执行特定的匹配规则了 */ $routes= array( '/' => array('_m'=>'wp_frontpage','_a'=>'index'), '/{id}'=> array('id'=>'/\d+/','_m'=>'wp_frontpage','_a'=>'index'), '/{_m}/{_a}/{id}'=> array('id'=>'/\d+/'), '/{_m}/{_a}'=> array() );
class Route { private static $instance = null; private $routepatterns=array(); private function __construct() { $routes = array(); include ROOT."/routes.php"; foreach($routes as $key=>$value){ $this->routepatterns[]=new RoutePattern($key,$value); } if(!isset($_SERVER['PATH_INFO'])) return false; $urlpath= $_SERVER['PATH_INFO']; $ismatch=$this->match_url($urlpath); $strip_urlpath=str_replace('/','',$urlpath); if(!$ismatch&&!empty($strip_urlpath)){ Content::redirect(PAGE_404); } } /** * 用路由规则匹配对应的url地址,匹配成功将对应url参数放入$_GET中 * @param string url地址 * @return bool 是否匹配成功 */ public function match_url($urlpath){ foreach($this->routepatterns as $router){ $urlargs=$router->match_url($urlpath); if($urlargs!==false){ $_GET=array_merge($urlargs,$_GET); return true; } } return false; } public function rewrite_url($urlparams){ foreach($this->routepatterns as $router){ $urlstr=$router->rewrite_url($urlparams); if($urlstr!==false){ return $urlstr; } } $actualparams=array(); foreach($urlparams as $arg=>$val){ $actualparams[]=$arg."=".urlencode($val); } $actualparamstr=implode('&', $actualparams); $rewriteurl="/index.php"; if(!empty($rewriteurl))$rewriteurl.="?{$actualparamstr}"; return $rewriteurl; } public static function init() { if (null == self::$instance) { self::$instance = new Route(); } return self::$instance; } } class RoutePattern{ //...... }