router.class.php 2.7 KB

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