Archive for September, 2009
PHP without tags
Monday, September 7th, 2009 | Uncategorized | No Comments
The PHP processor requires the start (<?) tag in order to begin parsing PHP code. It also likes the end tag (?>). This is because PHP was designed to be a template language that was parsed inside HTML, rather than a development language that assembles HTML templates.
Because of this paradigm shift, many developers don’t like the PHP tags for one reason or another. The good news is that it is possible to build a PHP application without tags, using some features built into the PHP engine.
We will create a “real” controller file, employing the eval() function, which parses a string as PHP code, without the need for the start tag.
The end result? A web application developed just like any other — without PHP tags. But there are two caveats:
- eval()ed code doesn’t understand $_GET, $_POST, $_SERVER, and other variables
- Processing time is slightly slower using eval().
We can fix #1 easily. eval()ed code understands global variables, so if we assign $_POST to a global $post variable.
#2 Can’t be resolved, but from my tests it isn’t a big problem. In a test of two identical loops of $t=$t*(log($i*sqrt($t))) where 0 <= i < 10000000, I found that the eval()ed loop ran only 0.62% slower than regular PHP code.
realfile.php
<?php
// since eval()ed code doesn't understand $_SERVER, we need
// to pass it over to global $server
global $server = $_SERVER;
// assuming $_GET['fakefile'] returns a filepath, we can open it using file_get_contents()
// file_get_contents() returns a string
// finally, eval() evaluates the string as PHP code and outputs the result
eval(file_get_contents('/webroot/'.urldecode($_GET['fakefile'])));
?>
Then we can write a “fake” PHP program that does not require the start or end tags.
fakefile.php
// say hello to the IP address
global $server;
echo('Hello Real World from '.$server['SERVER_ADDR']);
When you access the url http://example.com/realfile.php?fakefile=fakefile.php, the realfile.php will open and process the fakefile.php into the browser, as if you had written fakefile.php with PHP tags:
http://example.com/realfile.php?fakefile=fakefile.php
Hello Real World
You may not want to use query strings on your site in place of a real URL in your web application. Luckily, you can take advantage of a feature of Apache that lets you convert a URL string into a query string (e.g. converting http://example.com/path/to/file -> http://example.com/realfile.php?fakefile=/path/to/file)
This means that you can quietly use an realfile.php as a controller that reads and processes other files. You can set this up by adding a RewriteRule directive to a .htaccess file:
.htaccess
# Capture the requested URL as $1 and pass it to the realfile.php file RewriteRule ^(.*)$ realfile.php?fakefile=$1
Now you can access the same realfile.php?fakefile=fakefile.php by typing http://example.com/fakefile.php into your browser.
http://example.com/fakefile.php
Hello Real World