Jul 21 2008
Alternative PHP Cache
I had a small conversation with a junior PHP developer and I was disappointed about the lack of knowledge on PHP caching. In this article I will cover some ideas about APC.
What is APC? Php.net offers a laconic presentation: ” The Alternative PHP Cache (APC) is a free and open opcode cache for PHP”. That’s awesome, but what exactly this APC does? If you are not familiar with PHP internal process, you should read the following paragraph. If you are familiar, just go to the APC manual and start using it.
Let me describe in few words how a request is processed in PHP:
Start Request -> Compilation (Convert PHP source into opcodes) -> Execute Opcodes -> End Request.
Some smart guys created an extension that modifies the schema as the following:
Start Request -> APC Cache (stored directly in memory) ->
a) Cache doesn’t exists -> Compilation (Convert PHP source into opcodes) -> Store Opcodes in APC Cache ->
b) Cache Exists ->
Execute Opcodes -> End Request.
The second schema looks maybe much more complicated then the first, but please take a closer look. The compilation of the source code isn’t made for every request and it’s executed only for the first time. This impressively reduces the time of script processing. Another important aspect of APC caching mechanism is the storage. Source files are stored on the disk and the reading process is very slow compared with the process of reading directly from the memory.
So, APC caches the intermediary code directly in the memory. That’s all? Actually not! Another impressive quality is that you are able to store some data and to persist it between requests. Let’s be more clear. Any data (constants, arrays etc) die at the end of the request and you should recreate them in the next request. If you want to extract a list of countries from the database, even the list rarely change, you need to hit the database, perform a query, extract the data and then use it. Let’s make this information persistent: apc_store(’countries’, $countries). That’s it! You have the country list in the memory for the entire server life.
Let me show you some piece of code that does exactly what described:
1 2 3 4 5 6 7 8 9 10 11 12 | <?php /** * countries.php file */ $stmt = $dbh->query('SELECT * FROM country'); $a_countries[0] = 'N/A'; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $a_countries[$row['country_id']] = ucwords($row['country_name']); } apc_store('countries', $a_countries); ?> |
78 79 80 81 | if (($a_countries = apc_fetch('countries')) === false) { require DIR_ROOT.'apc/countries.php'; } |
Performance improvements are impressive. Even a default deployment of APC improves the server performance and you are able to see that without a lot of measuring. Pages are just loading faster.
What you should know about APC, if you didn’t discovered by yourself already, is that: cache is global, even on a multiple virtual hosts environment. If vhost1.example.com stores a variable var1, then vhost2.example.com decides to store the same var1, the data stored by vhost1.example.com is overwritten. Right now I don’t have a solution for using APC in multiple virtual hosts environment, but this isn’t the purpose of this article.
Have fun!
