Created
March 10, 2012 18:42
-
-
Save brendo/2012443 to your computer and use it in GitHub Desktop.
PHP 5.4 Router
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @package toolkit | |
*/ | |
/** | |
* URL rewriter for use in conjunction with the PHP 5.4 internal HTTP server and `rounter.php`. | |
*/ | |
namespace Rewrite; | |
class Storage { | |
static $matches = array(); | |
} | |
/** | |
* Initialize the rewrite environment. | |
*/ | |
function initialize() { | |
set_environment($_SERVER['REQUEST_URI']); | |
} | |
/** | |
* Set important environment variables and re-parse the query string. | |
* @return boolean | |
*/ | |
function finalize() { | |
if (defined('REWRITER_FINALIZED')) return false; | |
define('REWRITER_FINALIZED', true); | |
if (\is_file($_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME'])) { | |
$_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME']; | |
} | |
if (isset($_SERVER['QUERY_STRING'])) { | |
$_GET = []; | |
parse_str($_SERVER['QUERY_STRING'], $_GET); | |
} | |
$_SERVER['PHP_SELF'] = $_SERVER['SCRIPT_NAME']; | |
return true; | |
} | |
/** | |
* Adjust the server environment variables to match a given URL. | |
* @param string $url | |
*/ | |
function set_environment($url) { | |
$url = rtrim($url, '&?'); | |
$request_uri = $script_name = $url; | |
$query_string = null; | |
if (strpos($url, '?') > 0) { | |
$script_name = substr($url, 0, strpos($url, '?')); | |
$query_string = substr($url, 1 + strpos($url, '?')); | |
} | |
$_SERVER['REQUEST_URI'] = $request_uri; | |
$_SERVER['SCRIPT_NAME'] = $script_name; | |
$_SERVER['QUERY_STRING'] = $query_string; | |
} | |
/** | |
* Parse regular expression matches. eg. $0 or $1 | |
* @param string $url | |
* @return string | |
*/ | |
function parse_matches($url) { | |
$replace = function($bit) { | |
return isset(Storage::$matches[$bit[1]]) | |
? Storage::$matches[$bit[1]] | |
: null; | |
}; | |
return preg_replace_callback('/\$([0-9]+)/', $replace, $url); | |
} | |
/** | |
* Parse Apache style rewrite parameters. eg. %{QUERY_STRING} | |
* @param string $url | |
* @return string | |
*/ | |
function parse_parameters($url) { | |
$replace = function($bit) { | |
return isset($_SERVER[$bit[1]]) | |
? $_SERVER[$bit[1]] | |
: null; | |
}; | |
return preg_replace_callback('/%\{([A-Z_+]+)\}/', $replace, $url); | |
} | |
/** | |
* Change the internal url to a different url. | |
* @param string $from Regular expression to match current url, or optional when used in conjunction with `test`. | |
* @param string $to URL to redirect to. | |
* @return boolean | |
*/ | |
function rewrite($from, $to = null) { | |
if (defined('REWRITER_FINALIZED')) return false; | |
$url = $_SERVER['SCRIPT_NAME']; | |
// From and To given: | |
if (isset($to)) { | |
$url = preg_replace($from, $to, $url); | |
} | |
// Use results from last test: | |
else { | |
$url = parse_matches($from); | |
} | |
set_environment( | |
parse_parameters($url) | |
); | |
return true; | |
} | |
/** | |
* Redirect the client to a different url. | |
* @param string $from Regular expression to match current url, or optional when used in conjunction with `test`. | |
* @param string $to URL to redirect to. | |
*/ | |
function redirect($from, $to = null) { | |
if (defined('REWRITER_FINALIZED')) return false; | |
$url = $_SERVER['SCRIPT_NAME']; | |
// From and To given: | |
if (isset($to)) { | |
$url = preg_replace($from, $to, $url); | |
} | |
// Use results from last test: | |
else { | |
$url = parse_matches($from); | |
} | |
$url = parse_parameters($url); | |
header('Location: ' . $url); exit; | |
} | |
/** | |
* Compare a regular expression against the current request, store the matches for later use. | |
* @return boolean | |
*/ | |
function test($expression) { | |
if (defined('REWRITER_FINALIZED')) return false; | |
return 0 < (integer)preg_match($expression, $_SERVER['SCRIPT_NAME'], Storage::$matches); | |
} | |
/** | |
* Does the current request point to a directory? | |
* @return boolean | |
*/ | |
function is_dir() { | |
if (defined('REWRITER_FINALIZED')) return false; | |
return \is_dir($_SERVER['DOCUMENT_ROOT'] . $_SERVER['REQUEST_URI']); | |
} | |
/** | |
* Does the current request point to a file? | |
* @return boolean | |
*/ | |
function is_file() { | |
if (defined('REWRITER_FINALIZED')) return false; | |
return \is_file($_SERVER['DOCUMENT_ROOT'] . $_SERVER['REQUEST_URI']); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Router for the testing HTTP server built into PHP 5.4. | |
* Use with the following command from the root directory | |
* of your Symphony installation: | |
* | |
* php -S localhost:8080 router.php | |
* | |
* If you need to add your own rules, copy this file and | |
* use it as your own custom router. | |
*/ | |
namespace Rewrite; | |
require_once 'symphony/lib/toolkit/class.rewrite.php'; | |
// Prepare environment: | |
initialize(); | |
// SECURITY - Protect crucial files | |
test('%^/manifest/(.*)%') | |
| test('%.+\.(sql|xsl)$%') | |
| test('%^/\.%') | |
&& die('<h1>Access Denied</h1>'); | |
// Do not apply rules when requesting actual files: | |
if (is_file()) return false; | |
// Make sure the URL ends in a trailing slash: | |
test('%(?=/$)%') | |
|| redirect('%^.+%', '$0/'); | |
// Remove references to index.php: | |
test('%/(symphony/)?index.php(/.*/?)%') | |
&& redirect('$1$2'); | |
// Admin area rewrite: | |
test('%^/symphony/?$%') | |
&& rewrite('/index.php?mode=administration&%{QUERY_STRING}') | |
&& finalize(); | |
test('%/symphony(\/(.*\/?))?$%') | |
&& rewrite('/index.php?symphony-page=$1&mode=administration&%{QUERY_STRING}') | |
&& finalize(); | |
// Frontend page rewrite: | |
rewrite('%^/(.*\/?)$%', '/index.php?symphony-page=$1&%{QUERY_STRING}') | |
&& finalize(); | |
if (isset($_SERVER['SCRIPT_FILENAME'])) { | |
include_once $_SERVER['SCRIPT_FILENAME']; | |
} | |
else { | |
include_once 'index.php'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment