| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 | 
							- <?php
 
- namespace KIF;
 
- use KIF\Core\Request;
 
- use KIF\Core\Config;
 
- use KIF\String\String;
 
- use KIF\Math\Math;
 
- /**
 
-  * 
 
-  * 路由类
 
-  * @author gaoxiaogang
 
-  *
 
-  */
 
- class Route {
 
- 	
 
- 	/**
 
- 	 * 
 
- 	 * Enter description here ...
 
- 	 * @var array 格式:array(
 
- 	 *     $route_file => array(
 
- 	 *     	   'instance'  => (Route),
 
- 	 *         'rules'	=> array(
 
- 	 *             (string) $rewrite_pattern	=> (array) $rule,
 
- 	 *             ... ,
 
- 	 *         ),
 
- 	 *         'reverse_rules' => array(
 
- 	 *             (string)$fingerprint => (string)$rewrite_pattern,
 
- 	 *             ... ,
 
- 	 *         ),
 
- 	 *     ),
 
- 	 * );
 
- 	 */
 
- 	static private $structs;
 
- 	
 
- 	protected $struct;
 
- 	
 
- 	# 禁止被外部new
 
- 	private function __construct($route_file) {
 
- 		if (!file_exists($route_file) || !is_file($route_file)) {
 
- 			$route_rules = array();
 
- 		} else {
 
- 			$route_rules = include($route_file);
 
- 		}
 
- 		$rules = array();
 
- 		$reverse_rules = array();
 
- 		if (!$route_rules || !is_array($route_rules)) {
 
- 			self::$structs[$route_file]['rules'] = $rules;
 
- 			self::$structs[$route_file]['reverse_rules'] = $reverse_rules;
 
- 			return;
 
- 		}
 
- 		
 
- 		foreach ($route_rules as $rewrite_pattern	=> $rule) {
 
- 			if (!isset($rule['a']) || !$rule['a']) {
 
- 				$rule['a'] = 'default';
 
- 			}
 
- 			$fingerprint = $this->generateFingerprint($rule);
 
- 			
 
- 			$rules[$rewrite_pattern] = $rule;
 
- 			$reverse_rules[$fingerprint] = $rewrite_pattern;
 
- 		}
 
- 		self::$structs[$route_file]['rules'] = $rules;
 
- 		self::$structs[$route_file]['reverse_rules'] = $reverse_rules;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 
 
- 	 * 生成指纹,方便反向rewrite时高效查找。
 
- 	 * @param array $args
 
- 	 * @return string
 
- 	 */
 
- 	private function generateFingerprint($args) {
 
- 		if (!isset($args['a'])) {
 
- 			$args['a'] = 'default';
 
- 		}
 
- 		$arg_eles = array_combine(array_keys($args), array_fill(0, count($args), null));
 
- 		if (isset($args['a']))
 
- 			$arg_eles['a'] = $args['a'];
 
- 		if (isset($args['c']))
 
- 			$arg_eles['c'] = $args['c'];
 
- 		ksort($arg_eles);
 
- 		return Math::md5_16(print_r($arg_eles, true));
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 
 
- 	 * @return KIF\Route
 
- 	 */
 
- 	static public function getInstance() {
 
- 		$route_file = Config::getInstance()->get('route_file');
 
- 		$route_file = realpath($route_file);
 
- 		if (!isset(self::$structs[$route_file])) {
 
- 			self::$structs[$route_file]['instance'] = new self($route_file);
 
- 		}
 
- 		self::$structs[$route_file]['instance']->struct = & self::$structs[$route_file];
 
- 		return self::$structs[$route_file]['instance'];
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 
 
- 	 * 实现细节:
 
- 	 *     根据当前app的路由配置,查找到指定条目,并将当前path里携带的参数存放进 $_GET和$_REQUEST变量里
 
- 	 * 对当前请求路由
 
- 	 * 
 
- 	 */
 
- 	public function rewrite() {
 
- 		$path = Request::getInstance()->path();
 
- 		$rules = $this->struct['rules'];
 
- 		foreach ($rules as $pattern => $rule) {
 
- 			$pattern = "#^{$pattern}$#";
 
- 			if (preg_match($pattern, $path, $matches)) {
 
- 				foreach ($rule as $param	=> $paramVal) {
 
- 					if ($paramVal{0} != '$') {
 
- 						$_GET[$param] = $paramVal;
 
- 						$_REQUEST[$param] = $paramVal;
 
- 					} else {
 
- 						$match_pos = substr($paramVal, 1);
 
- 						if (Verify::naturalNumber($match_pos)) {
 
- 							$_GET[$param] = $matches[$match_pos];
 
- 							$_REQUEST[$param] = $matches[$match_pos];
 
- 						}
 
- 					}
 
- 					
 
- 				}
 
- 				break;
 
- 			}
 
- 		}
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 
 
- 	 * 获取经过路由后得到的请求参数。目前该方法被 Request::pageUrlTpl使用
 
- 	 * @return array 如果没有对应的路由,返回空数组
 
- 	 */
 
- 	public function getsRouteParams() {
 
- 		$route_params = array();
 
- 		$path = Request::getInstance()->path();
 
- 		$rules = $this->struct['rules'];
 
- 		foreach ($rules as $pattern => $rule) {
 
- 			$pattern = "#^{$pattern}$#";
 
- 			if (preg_match($pattern, $path, $matches)) {
 
- 				foreach ($rule as $param	=> $paramVal) {
 
- 					if ($paramVal{0} != '$') {
 
- 						$route_params[$param] = $paramVal;
 
- 					} else {
 
- 						$match_pos = substr($paramVal, 1);
 
- 						if (Verify::naturalNumber($match_pos)) {
 
- 							$route_params[$param] = $matches[$match_pos];
 
- 						}
 
- 					}
 
- 				}
 
- 				break;
 
- 			}
 
- 		}
 
- 		
 
- 		return $route_params;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 
 
- 	 * 反向rewrite。通过 $args 给定的参数,逆向rewrite规则,获取rewrite的url
 
- 	 * @param array $args 给定的参数值
 
- 	 * @return String
 
- 	 */
 
- 	public function reverse(array $args) {
 
- 		if (!$args) {
 
- 			return false;
 
- 		}
 
- 		if (!isset($args['a'])) {
 
- 			$args['a'] = 'default';
 
- 		}
 
- 		$arg_fingerprint = $this->generateFingerprint($args);
 
- 		if (isset($this->struct['reverse_rules'][$arg_fingerprint])) {
 
- 			$rewrite_pattern = $this->struct['reverse_rules'][$arg_fingerprint];
 
- 			if (strpos($rewrite_pattern, '(') === false) {
 
- 				return $rewrite_pattern;
 
- 			}
 
- 			$rule = $this->struct['rules'][$rewrite_pattern];
 
- 			
 
- 			$rule = array_filter($rule, function ($tmpV) {
 
- 				if ($tmpV{0} != '$') {
 
- 					return false;
 
- 				}
 
- 				return $tmpV;
 
- 			});
 
- 			
 
- 			$match_times = 0;
 
- 			$url = preg_replace_callback('#\([^)]+\)#', function ($matches) use (& $match_times, $rule, $args) {
 
- 				$match_times++;
 
- 				$key = array_search("\${$match_times}", $rule);
 
- 				if (!$key) {
 
- 					return false;
 
- 				}
 
- 				if (!isset($args[$key])) {
 
- 					return false;
 
- 				}
 
- 				
 
- 				return $args[$key];
 
- 			}, $rewrite_pattern);
 
- 			
 
- 			if (is_null($url)) {//说明发生错误了。
 
- 				return String::jointUrl('', $args);
 
- 			}
 
- 			
 
- 			return $url;
 
- 		}
 
- 		
 
- 		return String::jointUrl('', $args);
 
- 	}
 
- }
 
 
  |