PHP Software Engineering
Using the Built-in Web Server
Problem
You want to use PHP’s built-in web server to quickly spin up a test or simple website.
Solution
With PHP 5.4.0 or later, run the command-line PHP program with an -S argument giving a hostname and a port to listen on and you’ve got an instant PHP-enabled web server serving up the directory you started it in:
% php -S localhost:9876
Discussion
With only an -S host:port argument, the built-in web server treats the directory it was started in as the document root directory. If you start it from /home/roger, then a request to “/files/monkeys.php” corresponds to the file /home/roger/files/monkeys.php. Requests that map to a directory, rather then to a particular file, cause the built-in web server to first look for index.php in that directory, and then index.html in that directory.
To use a different document root directory, provide that with a -t argument when starting PHP. For example:
% php -S localhost:9876 -t /var/www
For more indirect mapping between request URLs and responses, specify a file containing PHP to do request routing as an additional argument:
% php -S localhost:9876 router.php
Before looking for a path that matches a request URL, PHP executes the code in router.php. PHP will only attempt to look for a matching path if that code returns false. This lets you do arbitrary response generation. Shows a request router that will return currency conversion rates between two currency codes provided in the URL.
Example Built-in web server request router
$parts = explode('/', $_SERVER['REQUEST_URI']);
// Expecting a request URI such as /USD/ISK, so make
// sure there are at least two parts and they are
// each three letters
if (! (isset($parts[1]) &&
preg_match('/[a-z]{3}/i', $parts[1]) &&
isset($parts[2]) &&
preg_match('/[a-z]{3}/i', $parts[2]))) {
header('Bad Request', true, 400);
print "Bad Request";
exit();
}
$quotes = 'http://download.finance.yahoo.com/d/quotes.csv?f=nl1&s=%s%s=X,%s%s=X';
$url = sprintf($quotes,
urlencode($parts[1]), urlencode($parts[2]),
urlencode($parts[2]), urlencode($parts[1]));
$response = file_get_contents($url);
$lines = explode("\n", trim($response));
foreach ($lines as $line) {
list($label, $rate) = str_getcsv($line);
print "<b>" . htmlentities($label) . "</b>: " .
htmlentities($rate) . "<br/>";
}
When Example is used as a request router by the built-in web server, $_SERVER['REQUEST_URI'] contains the request path the client asks for. In this case, we want to make requests such as /USD/EUR return the currency conversion rates between US dollars (USD) and Euro (EUR). So first, the code validates that the request URI contains two three-letter currency codes. Then, it plugs them into a URL that will download the conversion rate info from Yahoo! Finance. The response from that URL is a series of lines, each a set of CSV fields containing what kind of conversion rate it is and the numerical value of the rate. The foreach loop at the end of the code prints out the rates with some minimal HTML formatting. Shows the request URL and the output when asking for conversion between Icelandic krónur and Japanese Yen. In this example, the server has been started on port 9876.
Figure Currency conversion request router in action
No comments:
Post a Comment