Route.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. class Route {
  3. protected static $routes = array();
  4. protected static $patterns = array();
  5. protected static $groupStack = array(array());
  6. public static function match($methods, $uri, $action) {
  7. return self::addRoute(array_map('strtoupper', (array)$methods), $uri, $action);
  8. }
  9. public static function any($uri, $action) {
  10. return self::addRoute(array('GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'), $uri, $action);
  11. }
  12. public static function get($uri, $action) {
  13. return self::addRoute(['GET', 'HEAD'], $uri, $action);
  14. }
  15. public static function post($uri, $action) {
  16. return self::addRoute('POST', $uri, $action);
  17. }
  18. public static function put($uri, $action) {
  19. return self::addRoute('PUT', $uri, $action);
  20. }
  21. public static function patch($uri, $action) {
  22. return self::addRoute('PATCH', $uri, $action);
  23. }
  24. public static function delete($uri, $action) {
  25. return self::addRoute('DELETE', $uri, $action);
  26. }
  27. public static function group(array $attributes, Closure $callback) {
  28. self::$groupStack[] = array_merge(self::getGroup(), $attributes);
  29. call_user_func($callback);
  30. array_pop(self::$groupStack);
  31. }
  32. public static function getGroup() {
  33. return self::$groupStack[count(self::$groupStack) - 1];
  34. }
  35. public static function pattern($name, $pat) {
  36. self::$patterns[$name] = $pat;
  37. }
  38. public static function dispatch() {
  39. foreach (self::$routes as $route) {
  40. if (self::checkRoute($route)) {
  41. return $route;
  42. }
  43. }
  44. become404Page();
  45. }
  46. protected static function addRoute($methods, $uri, $action) {
  47. if (is_string($methods)) {
  48. $methods = [$methods];
  49. }
  50. $cur = array();
  51. $cur['methods'] = $methods;
  52. $cur['uri'] = rtrim($uri, '/');
  53. $cur['action'] = $action;
  54. $cur = array_merge(self::getGroup(), $cur);
  55. self::$routes[] = $cur;
  56. return $cur;
  57. }
  58. protected static function checkRoute($route) {
  59. if (!in_array(UOJContext::requestMethod(), $route['methods'])) {
  60. return false;
  61. }
  62. $rep_arr = array();
  63. foreach (self::$patterns as $name => $pat) {
  64. $rep_arr['{'.$name.'}'] = "(?P<$name>$pat)";
  65. }
  66. $rep_arr['/'] = '\/';
  67. $rep_arr['.'] = '\.';
  68. $matches = array();
  69. if (isset($route['domain'])) {
  70. $domain_pat = strtr($route['domain'], $rep_arr);
  71. if (!preg_match('/^'.$domain_pat.'$/', UOJContext::httpHost(), $domain_matches)) {
  72. return false;
  73. }
  74. $matches = array_merge($matches, $domain_matches);
  75. }
  76. $uri_pat = strtr($route['uri'], $rep_arr);
  77. if (!preg_match('/^'.$uri_pat.'$/', rtrim(UOJContext::requestPath(), '/'), $uri_matches)) {
  78. return false;
  79. }
  80. $matches = array_merge($matches, $uri_matches);
  81. foreach ($matches as $key => $val) {
  82. if (!is_numeric($key)) {
  83. $_GET[$key] = $val;
  84. }
  85. }
  86. return true;
  87. }
  88. }