PageRenderTime 62ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 0ms

/webphp/lib/Web.php

https://bitbucket.org/salimane/webphp
PHP | 233 lines | 127 code | 39 blank | 67 comment | 15 complexity | 781c3dc8284d7250fe88b956c4fb3072 MD5 | raw file
  1. <?php
  2. /**
  3. * web loader
  4. * @author Salimane Adjao Moustapha
  5. */
  6. class Web
  7. {
  8. protected $_urls = null;
  9. protected $_requestUrl = null;
  10. public $params = null;
  11. static protected $_instance = NULL;
  12. /**
  13. * create instance of Web object. Only use this method
  14. * to get an instance of Web.
  15. *
  16. * @author Salimane Adjao Moustapha
  17. */
  18. public static function &instance()
  19. {
  20. if (self::$_instance == NULL) {
  21. self::$_instance = new Web();
  22. }
  23. return self::$_instance;
  24. }
  25. /**
  26. * requestUri
  27. *
  28. * inspects $_SERVER['REQUEST_URI'] and returns a sanitized
  29. * path without a leading/trailing slashes
  30. * @return void
  31. * @author Salimane Adjao Moustapha
  32. */
  33. private function requestUri()
  34. {
  35. // have seen apache set either or.
  36. $uri = isset($_SERVER['REDIRECT_URL']) ? $_SERVER['REDIRECT_URL']
  37. : $_SERVER['REQUEST_URI'];
  38. // sanitize it
  39. $uri = filter_var($uri, FILTER_SANITIZE_URL);
  40. // kill query string off REQUEST_URI
  41. if ( strpos($uri,'?') !== false ) {
  42. $uri = substr($uri,0,strpos($uri,'?'));
  43. }
  44. // strip off first slash
  45. if(substr($uri, 0, 1) == "/"){
  46. $uri = substr($uri, 1);
  47. }
  48. // knock off last slash
  49. if (substr($uri, -1) == "/") {
  50. $uri = substr($uri, 0, -1);
  51. }
  52. $this->request_uri = $uri;
  53. }
  54. /**
  55. * send 303 by default so browser won't cache the 200 or 301 headers
  56. *
  57. * @param string $location
  58. * @param string $status
  59. * @return void
  60. * @author Salimane Adjao Moustapha
  61. */
  62. public static function redirect($location, $status=303)
  63. {
  64. self::httpHeader($status);
  65. header("Location: $location");
  66. }
  67. /**
  68. * send header code to browser
  69. *
  70. * @param string $code
  71. * @return void
  72. * @author Salimane Adjao Moustapha
  73. */
  74. public static function httpHeader($code)
  75. {
  76. $http = array (
  77. 100 => "HTTP/1.1 100 Continue",
  78. 101 => "HTTP/1.1 101 Switching Protocols",
  79. 200 => "HTTP/1.1 200 OK",
  80. 201 => "HTTP/1.1 201 Created",
  81. 202 => "HTTP/1.1 202 Accepted",
  82. 203 => "HTTP/1.1 203 Non-Authoritative Information",
  83. 204 => "HTTP/1.1 204 No Content",
  84. 205 => "HTTP/1.1 205 Reset Content",
  85. 206 => "HTTP/1.1 206 Partial Content",
  86. 300 => "HTTP/1.1 300 Multiple Choices",
  87. 301 => "HTTP/1.1 301 Moved Permanently",
  88. 302 => "HTTP/1.1 302 Found",
  89. 303 => "HTTP/1.1 303 See Other",
  90. 304 => "HTTP/1.1 304 Not Modified",
  91. 305 => "HTTP/1.1 305 Use Proxy",
  92. 307 => "HTTP/1.1 307 Temporary Redirect",
  93. 400 => "HTTP/1.1 400 Bad Request",
  94. 401 => "HTTP/1.1 401 Unauthorized",
  95. 402 => "HTTP/1.1 402 Payment Required",
  96. 403 => "HTTP/1.1 403 Forbidden",
  97. 404 => "HTTP/1.1 404 Not Found",
  98. 405 => "HTTP/1.1 405 Method Not Allowed",
  99. 406 => "HTTP/1.1 406 Not Acceptable",
  100. 407 => "HTTP/1.1 407 Proxy Authentication Required",
  101. 408 => "HTTP/1.1 408 Request Time-out",
  102. 409 => "HTTP/1.1 409 Conflict",
  103. 410 => "HTTP/1.1 410 Gone",
  104. 411 => "HTTP/1.1 411 Length Required",
  105. 412 => "HTTP/1.1 412 Precondition Failed",
  106. 413 => "HTTP/1.1 413 Request Entity Too Large",
  107. 414 => "HTTP/1.1 414 Request-URI Too Large",
  108. 415 => "HTTP/1.1 415 Unsupported Media Type",
  109. 416 => "HTTP/1.1 416 Requested range not satisfiable",
  110. 417 => "HTTP/1.1 417 Expectation Failed",
  111. 500 => "HTTP/1.1 500 Internal Server Error",
  112. 501 => "HTTP/1.1 501 Not Implemented",
  113. 502 => "HTTP/1.1 502 Bad Gateway",
  114. 503 => "HTTP/1.1 503 Service Unavailable",
  115. 504 => "HTTP/1.1 504 Gateway Time-out"
  116. );
  117. header($http[$code]);
  118. }
  119. /**
  120. * inspect urls, find matched class and then run requested method
  121. *
  122. * @param string $array
  123. * @param string $_baseURLPath
  124. * @return void
  125. * @author Salimane Adjao Moustapha
  126. */
  127. public static function run(array $urls)
  128. {
  129. if (empty($urls)) {
  130. throw new Exception("You must pass an array of valid urls to web::run()");
  131. return;
  132. }
  133. // get instance of Web
  134. $instance = self::instance();
  135. // process the request uri
  136. $instance->requestUri();
  137. $route = array();
  138. foreach ($urls as $url_path => $options) {
  139. if (preg_match($url_path, $instance->request_uri, $matches)) {
  140. // assuming pattern => array(class, function) in URLS array
  141. $route = array_merge($matches, array('module' => $options));
  142. unset($matches);
  143. $instance->params = $route;
  144. break;
  145. }
  146. }
  147. // if there is no uri match - module not at least set, throw a 404 error.
  148. if (!array_key_exists('module', $route)) {
  149. throw new RequestErrorException("Page not found.", 404);
  150. return;
  151. }
  152. // lets check matches for named patterns
  153. // be aware this is somewhat tied into __autoload function
  154. $class_to_load = $route['module'][0];
  155. // finds it based on __autoload function
  156. // instantiate class
  157. $loaded_class = new $class_to_load();
  158. // see if class has any pre-run hooks
  159. if (method_exists($loaded_class, 'preRun')) {
  160. $retval = $loaded_class->preRun();
  161. // if pre-run hook returns false, stop processing.
  162. if($retval === false) {
  163. return;
  164. }
  165. }
  166. // check for class method based on REQUEST_METHOD
  167. $method = $route['module'][1];
  168. // see if currently loaded class even supports it
  169. if (!method_exists($loaded_class, $method)) {
  170. throw new RequestErrorException("HTTP Method not supported by class.", 405);
  171. return;
  172. }
  173. // run request
  174. $loaded_class->$method();
  175. // see if class has any post-run hooks
  176. if (method_exists($loaded_class, 'postRun')) {
  177. $retval = $loaded_class->postRun();
  178. // if post-run hook returns false, stop processing.
  179. if($retval === false) {
  180. return;
  181. }
  182. }
  183. }
  184. /**
  185. * params
  186. *
  187. * @return stored web params from request_uri
  188. * @author Salimane Adjao Moustapha
  189. */
  190. public static function params()
  191. {
  192. return self::instance()->params;
  193. }
  194. }