PHP might be the most often used Internet programming language. One reason might be it's so simple and docile even a beginner without much experience can use it.
When a website becomes older and mature, and starts to attract more people a day, many webmasters face a new competition: keep the scripts running, performing good enough to be usable to their visitors. This is the time where one has to think about performance-tuning PHP. One way to achieve better performance is, to plug in better hardware. Another way (the one we choose for this article) is to fine-tune the software side at PHP level.
Websites are very different from the programs you run on your desktop, although both are complex applications. On the desktop you start an application, use it as long as you like, and then close it. The application stays in memory all the time on the desktop. During application termination the operating system (e.g. Windows or Linux) cleans up the application footprint.
The difference to web applications like those coded in PHP or any other common web language is, the application is started, executed and terminated at each page refresh. This circumstance should make clear to you what a huge overhead a PHP script causes.
One of the worst things is, the application loses all stored in RAM when exiting, thereby it has to load many things again and again with each page view. To reduce the load of reloading data, caching is used.
A cache is a fast and usually volatile data storage. Caching means to provide faster access to data that is often loaded but seldom updated. Caching is always optional: the software would work without, but would be slower. Caching ist not limited to software. For example, the computer you use contains several caches. The CPU has some Megabytes of cache memory to avoid using the slow front-side bus to often. And your graphics adapter is that fast just because of caching. Finally, the Internet is that fast only because many servers use caches.
Typical implementations of caches in the PHP world:
Above you see the first two methods highlighted. That is, because an implementation of these two will be discussed in this article.
The heap is a programs global scope, for which all variables can be accessed from any function or class method. The heap is reserved on initialization of your programs and is maintained until the script ends. There are two ways to put variables on the PHP heap:
The former is meant for the procedural programmers among you, the latter for the object oriented. I prefer object orientation, as it's more clean and easy to maintain OOP code, and therefore more simple to build an effective caching mechanism. PHP 5 offers quite mature OO. It doesn't matter much here which one you decide to use. You just have to make your own decision.
Putting your variable cache into the top level of a script is the most simple approach you might already have used intuitively.
<?php $my_cache = array(); // cache implementation as assoacitive array $my_cache['foo'] = 'a string'; // assign a value for later use function my_func(){ global $my_cache; // make the cache available inside a function $my_cache['bar'] = new an_object(); // assign an object if you like } ?>
By storing data in a global variable (on the heap) of the script, it will be ready for later use without having to load it again. Let us see how this could work with object orientation:
<?php static class my_cache{ private static $data; function get( $name ){ if( isset(self::data[$name] ){ return self::$data[$name]; } throw new Exception("cache fault: '{$name}' unknown. Your should use exists('{$name}') before get('{$name}')."); } function set( $name, $value ){ self::$data[$name] = $value; } function exists( $name ){ if( isset(self::$data[$name]) ){ return true; }else{ return false; } } } // using the cache class: $foo = 'bar'; my_cache::set( 'foo', $foo ); $cached_foo = my_cache::get('foo'); // Best practice would be to check for existance before querying cached values. // Our class would otherwise raise an exception to make sure the program // will go on with proper values. if( my_cache::exists('x') ){ $x = my_cache::get('x'); // get x from the cache if existing }else{ my_cache::set('x', 'init value of x'); // initialize x if not already done } ?>
The above is really the most simple way to speed up your PHP applications, as they will not need to load objects or variables each time you use it anywhere in the code. Just ask the cache if it knows a value of that name, and if not, load and initialize the variable and store it in the cache for later use.
For the sake of simplicity, the above code is of course not very efficient. It for example does not cache the PHP script itself, nor does it cache the variables for later use in other scripts: the cache is highly volatile and will be cleared at script termination.
Persitency in our case means to make the cache class my_cache store its data somewhere in a non-volatile location, for example on hard disk or inside a database.
The class developed above is a perfect starting point to do implement this extension and again attests OOP is a good thing. All we have to do is to make get() and exists() to load the data from disk if available, and set() to store the data on disk in case the data changed.
[TO BE CONTINUED]
Nice thanx!
Nice thanx!