Original article posted to PHP Advent 2008. Happy Christmas!
Take a simple PHP trick and follow it on a huge tangent to the philosophy of good web architecture.
It’s an honor to be asked to share my ideas with the PHP community. When Chris and Sean asked me to write an entry for the Advent Calendar, I had to accept. Like last year, this article will be quite long. If you need something short and sweet like the other advent entries, you can just read the first section. But if you read it all, there might be a worthwhile concept buried in this logorrhea.
Funky Caching
Funky Caching is an obscure trick often attributed to Rasmus but actually invented by Stig. It is also known as the “ErrorDocument trick,” “Smarter Caching” and “Rasmus’s Trick.” It was first presented by PHP creator, Rasmus Lerdorf, in his fun Tips and Tricks talk.
It’s entails the following:
First you create an ErrorDocument line in your apache.conf.
ErrorDocument 404 /error.php
What this does is tell the webserver to redirect all missing files to a PHP script called “error.php” in your directory root. You then create this handler:
$filepath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //or $_SERVER['REDIRECT_URL']
$basepath = dirname(__FILE__).DIR_SEP;
// Test to see if you can work with it
if (false) { //…EDIT…
//output a 404 page
include('404.html'); // see http://www.alistapart.com/articles/perfect404/ for tips
return;
}
// Generate the file
// …EDIT…
$data = 'something';
// Don't send 404 back, send 200 OK because this is a pretty smart 404
// not a clueless one! http://www.urbandictionary.com/define.php?term=404
header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));
//Show the file
echo $data;
//Store the page to bypass PHP on the next request. Use a temp file with a
// link trick in order to avoid race conditions between concurrent PHP
// processes.
$tmpfile = tempnam($basepath.'tmp','fc');
$fp = f_open($tmpfile,'w'); //remove the "_" this is crashing my blog syntax hilighter
fputs($fp, $data);
fclose($fp);
@link($basepath.$filepath, $tmpfile); //suppress errors due to losing race
unlink($tmpfile);
Other than the two areas delimited by …EDIT…, the code above is pretty canonical.
What does this trick do? Basically, when a file doesn’t exist, it gives an opportunity for PHP to create the data and return it instead of a 404 error page.
But after that is where the extra magic happens. It places the generated file directly into the web server path. What this means is that the next request to the same web resource goes directly for that resource without starting up this code and regenerating the data. Thus PHP never gets instantiated again.
At that point it truly becomes PHP without PHP.
Words have meaning through paradigm
The foundation of Steve McConnell’s seminal text, Code Complete, was that software development should be based around the paradigm of construction. But that was fundamentally flawed because of the mythical man-month—the “man-month” term itself originally coming from construction work. We now know McConnell was wrong and software isn’t construction, it is engineering. And we’re called “software engineers,” not “software workers” for this reason: we’re engineers, not construction workers.
My title at Tagged is currently “software architect.” And I have a “radical” idea that maybe titles are that way because they mean something. Meaning that if I’m hired as a software architect then I should think like an architect and find my inspiration from architecture.
Fallingwater
Nestled along a creek in the woods of southwestern Pennsylvania is a house that’s angular features are cantilevered 40 feet above a waterfall. This was the summer home of the Kaufmann family, owners of a Pittsburgh department store. (I remember that department store well because I spent days next to it in a neighboring newsstand reading issues of MAD magazine and Cracked.)
When I was a kid, my dad took us to visit the place, and I became one of millions of visitors to Fallingwater, a home that on its inception was hailed by TIME magazine and became known as the quintessential example of the organic architecture of architect Frank Lloyd Wright.
Why is Fallingwater, a summer home for a Pittsburgh family, so obviously beautiful that hundreds of thousands make the trek (50 miles from the nearest city) each year, that it was voted “best all-time work of American architecture” in 1991 by the American Institute of Architects, that pictures of it are as instantly recognizable as any natural wonder?
Maybe it’d be enlightening to consider how Frank Lloyd Wright built it. Before he started, he commissioned a survey to of the entire topography around the waterfall and had them include all trees and boulders. He then came up with an idea of a cantilevered house that would stretch in a manner that would look like it floated in air above the waterfall.
But more important, perhaps are details such as these:
- A staircase connects the house directly to the stream below. The stream and waterfall, though not seen, can be heard in all parts of the house.
- Windows wrap around the entire building such that the tungsten lighting of the interior would complement the fall foliage and the house and greenery would merge optically throughout the house.
- This glass was often caulked directly to each other and to the steel frame or stone walls to further symbolize the lack of barriers between the construction and the surrounding nature.
- The driveway trellis had a semi-circular cutaway to accommodate an existing tree.
- The stone floor in the living room, quarried from local rocks, is actually built around a boulder undisturbed from its original position in the site.
From details like that to the whole view taken in at once, one gets a feeling that, in spite of the sharp horizontal and vertical lines of the building, the whole lives in harmony with its environment “instead of lording above [it] in an isolated spot as a man-made imposition.”
Frank Lloyd Wright designed on the principles of: “organic, democratic, plasticity, continuity.” We can see how this example holds true to those values.
Could this building have been built anywhere else?
Why is Funky Caching trick so prevalent in the PHP world?
If you look at Funky Caching, it doesn’t need PHP to implement it. This begs the question as to why it first appeared in the PHP world? Why is this obscure design pattern so ubiquitous in the PHP world? In fact, you, as a PHP developer, use it every day when you visit the PHP.net website the instant you type http://www.php.net/strstr to figure out the order of the needle in the haystack.
A cynic would say because PHP is so slow to execute it needs solutions like this to perform well. The problem with this argument is that no single web language outperforms the fastest static servers out there, or even come close to the slow ones. There is no web language that wouldn’t benefit from this trick.
But there is truth to the cynic’s statement. The PHP world may have discovered this first because it trades off speed of execution with speed and ease of development. As Andrei mentioned earlier, that is fundamental to its design. In fact, all dynamically typed scripting languages make this tradeoff.
The ubiquity of this trick in the PHP world is because it—like Frank Lloyd Wright’s Fallingwater—lives in harmony with its environment. The environment is an Apache web server, persistent data store in the form of a relational database, and the demands of large-scale consumer-facing web. Would this solution exist without an Error Document handler built into Apache? Would this solution exist if we didn’t persist content on a (relatively) slow data store like a database? Would this solution exist if the consumer didn’t demand millisecond response time for dynamic content?
Funky Caching in the PHP world lives in harmony with that environment. It lives in harmony with PHP itself.
The architectural principles of PHP itself
PHP is a language that is designed to solve the “web problem.”
PHP is built on as a component of the web architecture as Maggie mentioned earlier. Without Apache serving it, without a database backing it, without the demands of the web behind it, without thousands of hosting sites installing it, without hundreds of open-source packages written in it, it would be useless.
The language itself, like Fallingwater, is customized for the problem at hand and compliments the environment in which it lives. Just like Wright’s design lived true to his principles, so does PHP and its solutions live true to its principles: “cheap, scalable, pragmatic.”
When using PHP, Let us not forget PHP’s three principles that attract us to the language in the first place:
- Cheap (cheap on developer time and resources): “A project done in Java will cost 5 times as much, take twice as long, and be harder to maintain than a project done in a scripting language such as PHP or Perl.” —Phillip Greenspun
- Scalable (shared-nothing architecture): “That a Java servlet performs better than a PHP script, under optimal conditions [has] nothing to do with scalability. The point is can your application continue to deliver consistent performance as volume increases…PHP delegates all the “hard stuff” to other systems.” —Harry Fuecks
- Pragmatic (designed to solve the web problem): “PHP is not about purity in CS principles or architecture, it is about solving the ugly web problem with an admittedly ugly, but extremely functional and convenient solution. If you are looking for purity you are in the wrong boat. Get out now before you get hit by a wet cat!” —Rasmus Lerdorf
Could this “ugly, but extremely functional and convenient” web language been built to solve anything other than the “ugly web problem”?
Bellefield Tower
One block from where my mother used to work, on the corner of Fifth Avenue and Bellefield in Pittsburgh, stands a strange sight. A very modern building wraps around in a Jobsian-loving rounded rectangle, narrowly avoiding a gothic Romanesque tower a century its senior. An uglier and more out-of-place architectural juxtaposition I have never yet seen.
If you weren’t in Pittsburgh in the late 1980’s you wouldn’t have understood how his could have happened. On this ground once stood the original Bellefield church built in the 1880’s. Since its congregation had been moved further down Fifth Avenue, the building was sold a century later to developers trying to exploit the new business attracted by the Pittsburgh Supercomputing Center and the joint CMU/Pitt software building. They wanted to level it and build a new building, but were blocked when people mobilized to save the old tower. The developer then proceeded to honor this by demolishing everything but the tower and building the ironically-named “Bellefield Towers” next to it.
You can see the current Bellefield Presbyterian Church as an common example of the gothic architecture of the area. You can also note Carnegie Library of Pittsburgh and the Cathedral of Learning—both next door, both reflecting the gothic Romanesque architecture, and both figuring prominently in iconic photos of the most famous game in baseball.
Why is Bellefield Towers so obviously ugly? the old Bellefield Church tower stands next to Bellefield Towers with a “sawed-off” quality to it. The curved modern architecture of the latter serves only to emphasize how it was built with no consideration of the surrounding environment. The Oakland and Shadyside areas of the city that the old Bellefield Church straddled contains many unique examples of this Romanesque gothic architecture. When faced with a gorgeous 100-year old example of the area’s architecture, instead of working with the environment like Frank Lloyd Wright did with Fallingwater—in the same area of Pennsylvania no less!—the developer simply sawed it off!
I remember watching it happen, and this (literal) architectural lesson guides me to this day about the follies of architectural hubris in software.
What hubris?
“What hubris?”
Well have you ever seen developers write code without considering the environment in which the code will live?
I guess my big beef with most frameworks is that they’re often written with no consideration of the environment—that is almost by definition. The best frameworks are ones that are less frameworks than applications which force constraints of an environment.
As Paul mentioned earlier, even if you build it your way and customize the solution for your application, it’s still a framework. But it’s a framework most likely to have at least one successful user… yourself.
“I’m a developer, I can make the software conform to my needs.”
Oh really? That sounds a lot like trying to “lord over the environment with an isolated man-made imposition.”
“But what I mean is it’s all man-made in software, there is no environment.”
You don’t develop in a community as Chris mentioned earlier? That’s environment. You never took over a project you didn’t write or worked at a company with a pre-existing code base? That’s environment. You never dealt with an installation problem because your host was configured differently then your development environment? That’s environment. You never had business needs trump the little feature creature sitting on your shoulder? That’s environment. You’ve never listened to a user request, as Paul mentioned earlier? That’s environment.
“There is no danger of that environment being different.”
When I joined my current company, they had a couple services written in Java, only Zend Accelerator could code cache their PHP 4 installation, Oracle RAC powered the back-end and development occurred by engineers working in cubes with a relatively heavyweight waterfall development process.
Even though I prefer Python to Java for services, we’ve increased our Java development to around 40% of our code base! Even though I prefer MySQL to Oracle, we still use Oracle as our back-end. Even the transition to the open office occurred after it became apparent the company had outgrown the cube-space.
Why? Because that is the environment and your solutions have to work within that environment. Anything else is architectural hubris.
“But that’s not an architecture decision.”
Let’s say it is the early days of social networking and you join a company that is using Java/J2EE instead of PHP, or Oracle instead of MySQL, or they’re using Perl/Mason instead of your favorite (PHP) framework, as Marco mentioned earlier—there are so many to choose from that the number is second only to Java.
Do you go in and say your experience building a CMS or e-store trumps their experience working on a nascent social network? Do you replace all the Java engineers with PHP ones? Do you replace MySQL with Oracle? Do you rewrite the site from scratch using your favorite framework?
These things may have happened and more.















