Normal.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. namespace Qii\Router\Parse;
  3. /**
  4. * Route规则文件
  5. * 兼容以前版本的匹配规则
  6. *
  7. * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-10-24 23:11
  8. * @version 1.2
  9. */
  10. class Normal
  11. {
  12. const VERSION = '1.2';
  13. private $config;
  14. public function __construct()
  15. {
  16. }
  17. /**
  18. * 设置路由规则
  19. * @param Array $config 路由规则
  20. */
  21. public function setConfig($config)
  22. {
  23. $this->config = $config;
  24. }
  25. /**
  26. * 路由转发, 转发对应的规则中xx不能为*
  27. *
  28. * @param string $url url链接
  29. * @param String $controller
  30. * @param String $action
  31. * @return Array ($controller, $action);
  32. *
  33. * *:* => *:yyy 所有controller和action都转发到 *->yyy
  34. * *:* => yy:* 所有转发到xxx->*, 这里的*,前边对应的是什么,后边就对应转发到什么,比如: *:xxx => yy:yyy
  35. * xx:* => yy:* xx中对应的方法转发到yy对应的方法
  36. * xx:* => yy:yyy xxx Controller转发到 yy->yyy
  37. * *:xxx => yy:yyy 所有Controller转发到 yy->yyy
  38. * xxx:*(yy):第三个参数 => {1}:* 转发xxx:yy => yy:第三个参数
  39. */
  40. public function parse($url, $controller, $action)
  41. {
  42. if (!$this->config) {
  43. return array('controller' => $controller, 'action' => $action);
  44. }
  45. if($url == '') $url = 'index/index.html';
  46. $url = ltrim($url, '/');
  47. $dirName = pathinfo($url, PATHINFO_DIRNAME);
  48. $dirInfo = explode('/', $dirName);
  49. $fileName = pathinfo(ltrim($url, '/'), PATHINFO_FILENAME);
  50. if ($dirName == '.') {
  51. $dirInfo = array();
  52. }
  53. $dirInfo[] = $fileName;
  54. //补全路径
  55. if(count($dirInfo) == 1)
  56. {
  57. $dirInfo[] = 'index';
  58. }
  59. $dir = [];
  60. $match = ['key' => '', 'val' => '', 'url' => $url];
  61. if(isset($this->config['*:*'])) {
  62. list($controller, $action) = explode(':', $this->config['*:*']);
  63. $match['match'] = '*:*';
  64. $match['controller'] = $controller ? $controller : 'index';
  65. $match['action'] = $action ? $action : 'index';
  66. return $match;
  67. }
  68. foreach ($dirInfo AS $path) {
  69. $dir[] = $path;
  70. $notAll = join($dir, ':');
  71. if (isset($this->config[$notAll])) {
  72. $config = $this->config[$notAll];
  73. //匹配最长的规则
  74. if (strlen($config) > strlen($match['val'])) {
  75. $match = array_merge($match, ['key' => $notAll, 'val' => $config]);
  76. }
  77. }
  78. $joinPath = join($dir, ':') . ":*";
  79. if (isset($this->config[$joinPath])) {
  80. $config = $this->config[$joinPath];
  81. //匹配最长的规则
  82. if (strlen($config) > strlen($match['val'])) {
  83. $match = array_merge($match, ['key' => $joinPath, 'val' => $config]);
  84. }
  85. }
  86. }
  87. $match['dirInfo'] = $dirInfo;
  88. //如果match到就解析match的内容
  89. if ($match['val']) {
  90. $matches = explode(':', $match['val']);
  91. $match['matches'] = $matches;
  92. $action = array_pop($matches);
  93. $controller = join('\\', $matches);
  94. $controllerExplode = explode('\\', $controller);
  95. if (stristr($controller, '{1}')) {
  96. $pad = count($controllerExplode) - count($dirInfo);
  97. if ($pad > 0) {
  98. $dirInfo = array_pad($dirInfo, count($controllerExplode), 'index');
  99. }
  100. $controller = join('\\', array_slice($dirInfo, 0, count($controllerExplode)));
  101. }
  102. $action = $action == '{1}' || $action == '*' ? isset($dirInfo[count($controllerExplode)]) ? $dirInfo[count($controllerExplode)] : 'index' : $action;
  103. $match['controller'] = $controller;
  104. $match['action'] = $action;
  105. } else {
  106. $match['controller'] = isset($dirInfo[0]) ? $dirInfo[0] : 'index';
  107. $match['action'] = isset($dirInfo[1]) ? $dirInfo[1] : 'index';
  108. //匹配配置文件中以 * 开头的规则
  109. foreach($this->config as $key => $config)
  110. {
  111. if(stristr($key, '*:'))
  112. {
  113. list($sourceController, $sourceAction) = explode(':', $key);
  114. list($destController, $destAction) = explode(":", $config);
  115. $match['controller'] = $destController;
  116. if($sourceAction == '*') {
  117. $map['action'] = $destAction;
  118. }else if($map['action'] == $sourceAction){
  119. $map['action'] = $destAction;
  120. }
  121. }
  122. }
  123. }
  124. return $match;
  125. }
  126. }