router.php 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <?php
  2. /**
  3. * Functions for URL routing: given an URL, call the corresponding handler
  4. * function (the 'route' to the corresponding output).
  5. *
  6. * @author Taddeus Kroes
  7. * @version 1.0
  8. * @date 14-07-2012
  9. */
  10. namespace BasicWeb;
  11. require_once 'base.php';
  12. /**
  13. *
  14. *
  15. * <code>
  16. *
  17. * </code>
  18. *
  19. * @package BasicWeb
  20. * @todo Example
  21. */
  22. class Router extends Base {
  23. /**
  24. * The regex delimiter that is added to the begin and end of patterns.
  25. *
  26. * @var string
  27. */
  28. const DELIMITER = '%';
  29. /**
  30. * An associative array of regex patterns pointing to handler functions.
  31. *
  32. * @var array
  33. */
  34. private $routes = array();
  35. /**
  36. * Create a new Router instance.
  37. *
  38. * @param array $routes An initial list of routes to set.
  39. */
  40. function __construct(array $routes=array()) {
  41. foreach( $routes as $pattern => $handler )
  42. $this->add_route($pattern, $handler);
  43. }
  44. /**
  45. * Add a route as a (pattern, handler) pair.
  46. *
  47. * The pattern is regular expression pattern without delimiters. The
  48. * function adds '%^' at the begin and '$%' at the end of the pattern as
  49. * delimiters.
  50. *
  51. * The handler function must receive no arguments if the regex pattern
  52. * does not contain groups (which are contained in parentheses). If there
  53. * are groups, the matches for these are passed to the handler fucntion in
  54. * an array.
  55. *
  56. * @param string $pattern A regex pattern to mach URL's against.
  57. * @param mixed $handler The handler function to call when $pattern is matched.
  58. * @throws \InvalidArgumentException If $handler is not callable.
  59. */
  60. function add_route($pattern, $handler) {
  61. if( !is_callable($handler) )
  62. throw new \InvalidArgumentException(sprintf('Handler for patterns "%s" is not callable.', $pattern));
  63. $this->routes[self::DELIMITER.'^'.$pattern.'$'.self::DELIMITER] = $handler;
  64. }
  65. /**
  66. * Call the handler function corresponding to the specified url.
  67. *
  68. * If any groups are in the matched regex pattern, a list of matches is
  69. * passed to the handler function.
  70. *
  71. * @param string $url An url to match the saved patterns against.
  72. * @return mixed FALSE if no pattern was matched, the return value of the
  73. * corresponding handler function otherwise.
  74. */
  75. function call_handler($url) {
  76. foreach( $this->routes as $pattern => $handler ) {
  77. if( preg_match($pattern, $url, $matches) ) {
  78. array_shift($matches);
  79. return call_user_func_array($handler, $matches);
  80. }
  81. }
  82. return false;
  83. }
  84. }
  85. ?>