Support REQUEST_URI routing method

With Pico 1.0 you had to setup URL rewriting (e.g. using `mod_rewrite` on Apache) in a way that rewritten URLs follow the `QUERY_STRING` principles. Starting with version 1.1, Pico additionally supports the `REQUEST_URI` routing method, what allows you to simply rewrite all requests to just `index.php`. Pico then reads the requested page from the `REQUEST_URI` environment variable provided by the webserver. Please note that `QUERY_STRING` takes precedence over `REQUEST_URI`.
This commit is contained in:
Daniel Rudolf 2016-04-24 20:11:05 +02:00
parent d19621a908
commit 6465c2b0a9
No known key found for this signature in database
GPG Key ID: A061F02CD8DE4538
2 changed files with 50 additions and 19 deletions

View File

@ -1,13 +1,18 @@
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine On RewriteEngine On
#May be required to access sub-directories # May be required to access sub-directories
#RewriteBase / #RewriteBase /
# Deny access to internal dirs by passing the URL to Pico
RewriteRule ^(.git|config|content|content-sample|lib|vendor)(/|$) index.php [L]
# Enable URL rewriting
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA] RewriteRule ^ index.php [L]
RewriteRule ^(config|content|content-sample|lib|vendor)/.* - [R=404,L]
<IfModule mod_env.c> <IfModule mod_env.c>
# Let Pico know about available URL rewriting
SetEnv PICO_URL_REWRITING 1 SetEnv PICO_URL_REWRITING 1
</IfModule> </IfModule>
</IfModule> </IfModule>

View File

@ -656,13 +656,19 @@ class Pico
/** /**
* Evaluates the requested URL * Evaluates the requested URL
* *
* Pico 1.0 uses the `QUERY_STRING` routing method (e.g. `/pico/?sub/page`) * Pico uses the `QUERY_STRING` routing method (e.g. `/pico/?sub/page`)
* to support SEO-like URLs out-of-the-box with any webserver. You can * to support SEO-like URLs out-of-the-box with any webserver. You can
* still setup URL rewriting (e.g. using `mod_rewrite` on Apache) to * still setup URL rewriting to basically remove the `?` from URLs.
* basically remove the `?` from URLs, but your rewritten URLs must follow * However, URL rewriting requires some special configuration of your
* the new `QUERY_STRING` principles. URL rewriting requires some special * webserver, but this should be "basic work" for any webmaster...
* configuration on your webserver, but this should be "basic work" for *
* any webmaster... * With Pico 1.0 you had to setup URL rewriting (e.g. using `mod_rewrite`
* on Apache) in a way that rewritten URLs follow the `QUERY_STRING`
* principles. Starting with version 1.1, Pico additionally supports the
* `REQUEST_URI` routing method, what allows you to simply rewrite all
* requests to just `index.php`. Pico then reads the requested page from
* the `REQUEST_URI` environment variable provided by the webserver.
* Please note that `QUERY_STRING` takes precedence over `REQUEST_URI`.
* *
* Pico 0.9 and older required Apache with `mod_rewrite` enabled, thus old * Pico 0.9 and older required Apache with `mod_rewrite` enabled, thus old
* plugins, templates and contents may require you to enable URL rewriting * plugins, templates and contents may require you to enable URL rewriting
@ -675,23 +681,43 @@ class Pico
* enabled URL rewriting. In content files you can use the `%base_url%` * enabled URL rewriting. In content files you can use the `%base_url%`
* variable; e.g. `%base_url%?sub/page` will be replaced accordingly. * variable; e.g. `%base_url%?sub/page` will be replaced accordingly.
* *
* Heads up! Pico always interprets the first parameter as name of the
* requested page (provided that the parameter has no value). According to
* that you MUST NOT call Pico with a parameter without value as first
* parameter (e.g. http://example.com/pico/?someBooleanParam), otherwise
* Pico interprets `someBooleanParam` as name of the requested page. Use
* `/pico/?someBooleanParam=` or `/pico/?index&someBooleanParam` instead.
*
* @see Pico::getRequestUrl() * @see Pico::getRequestUrl()
* @return void * @return void
*/ */
protected function evaluateRequestUrl() protected function evaluateRequestUrl()
{ {
// use QUERY_STRING; e.g. /pico/?sub/page // use QUERY_STRING; e.g. /pico/?sub/page
// if you want to use rewriting, you MUST make your rules to $pathComponent = $_SERVER['QUERY_STRING'];
// rewrite the URLs to follow the QUERY_STRING method if (!empty($pathComponent)) {
// if (($pathComponentLength = strpos($pathComponent, '&')) !== false) {
// Note: you MUST NOT call the index page with /pico/?someBooleanParameter; $pathComponent = substr($pathComponent, 0, $pathComponentLength);
// use /pico/?someBooleanParameter= or /pico/?index&someBooleanParameter instead }
$pathComponent = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; if (strpos($pathComponent, '=') === false) {
if (($pathComponentLength = strpos($pathComponent, '&')) !== false) { $this->requestUrl = trim(rawurldecode($pathComponent), '/');
$pathComponent = substr($pathComponent, 0, $pathComponentLength); }
}
// use REQUEST_URI (requires URL rewriting); e.g. /pico/sub/page
if (($this->requestUrl === null) && $this->isUrlRewritingEnabled()) {
$basePath = dirname($_SERVER['SCRIPT_NAME']) . '/';
$basePathLength = strlen($basePath);
$requestUri = $_SERVER['REQUEST_URI'];
if (substr($requestUri, 0, $basePathLength) === $basePath) {
$requestUri = substr($requestUri, $basePathLength);
if (($requestUriLength = strpos($requestUri, '?')) !== false) {
$requestUri = substr($requestUri, 0, $requestUriLength);
}
$this->requestUrl = rtrim(rawurldecode($requestUri), '/');
}
} }
$this->requestUrl = (strpos($pathComponent, '=') === false) ? rawurldecode($pathComponent) : '';
$this->requestUrl = trim($this->requestUrl, '/');
} }
/** /**