Basic Apache
mod_rewrite
functionality can be simulated through the use of a PHP script
referenced from app.yaml
that will in turn load the desired script. This example
simulates the common PHP pattern that expects the variable $_GET['q']
to contain the
request path.
About mod_rewrite.php
To enable mod_rewrite functionality, your application needs to include
mod_rewrite.php
, which is the script that will be invoked for all requests to your
application to perform the request routing. As described in the comments the script will check for
the existence of root-level PHP scripts and invoke them while placing the path portion of
$_SERVER['REQUEST_URI']
in the $_GET['q']
variable.
<?php /** * @file * Provide basic mod_rewrite like functionality. * * Pass through requests for root php files and forward all other requests to * index.php with $_GET['q'] equal to path. The following are examples that * demonstrate how a request using mod_rewrite.php will appear to a PHP script. * * - /install.php: install.php * - /update.php?op=info: update.php?op=info * - /foo/bar: index.php?q=/foo/bar * - /: index.php?q=/ */ $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); // Provide mod_rewrite like functionality. If a php file in the root directory // is explicitly requested then load the file, otherwise load index.php and // set get variable 'q' to $_SERVER['REQUEST_URI']. if (dirname($path) == '/' && pathinfo($path, PATHINFO_EXTENSION) == 'php') { $file = pathinfo($path, PATHINFO_BASENAME); } else { $file = 'index.php'; // Provide mod_rewrite like functionality by using the path which excludes // any other part of the request query (ie. ignores ?foo=bar). $_GET['q'] = $path; } // Override the script name to simulate the behavior without mod_rewrite.php. // Ensure that $_SERVER['SCRIPT_NAME'] always begins with a / to be consistent // with HTTP request and the value that is normally provided. $_SERVER['SCRIPT_NAME'] = '/' . $file; require $file;
Example app
The following show a very simple application written to expect $_GET['q']
.
app.yaml
As you can see from this app.yaml
file, this application will provide two root-level
PHP scripts and serve static files out of a directory named downloads
.
application: mod_rewrite_simulator version: 1 runtime: php55 api_version: 1 handlers: # Example of handler which should be placed above the catch-all handler. - url: /downloads static_dir: downloads # Catch all unhandled requests and pass to mod_rewrite.php which will simulate # mod_rewrite by forwarding the requests to index.php?q=... (or other root-level # PHP file if specified in incoming URL. - url: /.* script: mod_rewrite.php
index.php
index.php
is a router-style index.php
which reads
$_GET['q']
to determine the request path.
<?php if ($_GET['q'] == '/help') { echo 'This is some help text.'; exit; } echo 'Welcome to the site!';
other.php
The following is an example of a root-level script that can be called directly. Many
PHP frameworks have scripts like install.php
or update.php
that would
behave similarly.
<?php echo 'Welcome to the other site.';
Example requests
Given the above example application the following requests would be handled as shown.
/
translates toindex.php
with$_GET['q'] = '/'
/help
translates toindex.php
with$_GET['q'] = '/help'
/other.php
translates toother.php
with$_GET['q'] = null
/downloads/foo_17.png
translates todownloads/foo_17.png
Avoid the need for mod_rewrite.php
Many PHP frameworks no longer depend on $_GET['q']
. Instead they make use of
$_SERVER['REQUEST_URI']
which works both with and without mod_rewrite
.
As such the latter is the preferred method on App Engine.
As used in mod_rewrite.php
a clean method of utilizing REQUEST_URI
is
the following:
<?php $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); if ($path == '/help') { echo 'This is some help text.'; exit; } echo 'Welcome to the site!';