router.class.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. require_once('path.class.php');
  3. require_once('response.class.php');
  4. require_once('request.class.php');
  5. class Router {
  6. private $_paths = [];
  7. private $_routers = [];
  8. private $_base = '/';
  9. private $responses = [];
  10. private $_handled = false;
  11. public function __construct($base = null, $paths = null){
  12. if($paths != null){
  13. $this->paths($paths);
  14. }
  15. if($base != null){
  16. $this->base($base);
  17. }
  18. }
  19. public function __get($name){
  20. switch($name){
  21. case 'base':
  22. return $this->_base;
  23. break;
  24. case 'handled':
  25. return $this->_handled;
  26. break;
  27. }
  28. }
  29. public function __clone(){
  30. // No cloning
  31. }
  32. public function __destruct(){
  33. $this->_paths = [];
  34. }
  35. public function __toString(){
  36. return "[Router]";
  37. }
  38. public function base($base){
  39. $this->_base = $base;
  40. }
  41. public function url($url){
  42. return preg_replace('/(\/+)/','/',$url);
  43. }
  44. public function prefix($prefix, Callable $fn){
  45. $found = false;
  46. foreach($this->_routers as $k => $router){
  47. if($router->base == $prefix){
  48. $found = true;
  49. $fn($router);
  50. break;
  51. }
  52. }
  53. if(!$found){
  54. $router= new Router($prefix);
  55. $this->_routers[] = $router;
  56. $fn($router);
  57. }
  58. }
  59. // fn = function(response,args){}
  60. public function path($path, Callable $fn){
  61. $obj = false;
  62. foreach($this->_paths as $k => $p){
  63. if($p->path == $path){
  64. $obj = $p;
  65. }
  66. }
  67. if(!$obj){
  68. $obj = new Path($path);
  69. array_push($this->_paths,$obj);
  70. }
  71. return $obj->handle($fn);
  72. }
  73. public function paths($paths){
  74. foreach($paths as $path => $fn){
  75. $this->path($path,$fn);
  76. }
  77. }
  78. public function clear(){
  79. $this->_paths = [];
  80. }
  81. public function handle($path, $req = null,$res = null,Callable $fn = null, Callable $onerror = null){
  82. if(strpos($path, $this->base) !== false){
  83. $path = substr($path,strpos($path,$this->base)+strlen($this->base));
  84. if($path[0] != '/'){
  85. $path = '/'.$path;
  86. }
  87. if(is_null($req)){
  88. $req = new Request();
  89. }
  90. if(is_null($res)){
  91. $res = new Response();
  92. }
  93. if(!in_array($res,$this->responses)){
  94. array_push($this->responses,$res);
  95. }
  96. $handled = false;
  97. foreach($this->_routers as $prefix => $router){
  98. $router->handle($path, $req, $res);
  99. $handled = $handled ||$router->handled;
  100. }
  101. ob_start();
  102. foreach($this->_paths as $k => $p){
  103. if($p->matches($path)){
  104. $handled = true;
  105. try{
  106. $p($req, $res, $p->args($path));
  107. }catch(Exception $e){
  108. if(!is_null($onerror)){
  109. $onerror($req, $res,$e);
  110. }else{
  111. throw $e;
  112. }
  113. }
  114. }
  115. }
  116. $this->_handled = $handled;
  117. if(!$handled && !is_null($fn)){
  118. $fn($req, $res);
  119. }
  120. $res->output .= ob_get_contents();
  121. ob_end_clean();
  122. }
  123. return $res;
  124. }
  125. }
  126. ?>