[ D O W N L O A D ]
If you have a dynamic website, written in PHP and your site is slow then this solution might help you.
Some times you have to have some nasty query then process the result afterwards which makes the whole thing even nastier and slow.
With PHPCache, you will be able to cache the result of that piece of code for as long as you want.
Suppose that your nasty script gets 100 hits per second, and you cache your script using PHPCache for just 1 minute at a time, the result is, in that one minute your server will run that piece of code only once.
PHPCache will only query the database for the result that was stored in the database 100 times in that one minute.
This will be a very quick process, since it’s only a primary key lookup (piece a cake) for MySQL and SQLite. These databases can handle 1000s of simple queries like these per second! But your server might only be able to process your code 5 times per second…
In fact I tested this and SQLite could retrieve the cache 2,300 per second, MySQL around 2,500 times!
PHPCache supports MySQL, MySQLi and SQLite extensions at this time but you are welcome to write and submit extensions for other database servers.
The other great thing about PHPCache is support for SQLite; SQLite is a very nice, quick little database that you can setup easily and you won’t need to have MySQL.
Here is an example usage of PHPCache:
require_once 'phpcache.class.php';
$database = array(
'type' => 'mysql',
'name' => 'YOUR DATABASE NAME',
'table' => 'PHPCache',
'user' => 'YOUR DATABASE USERNAME',
'pass' => 'YOUR DATABASE USERNAME\'S PASSWORD',
'host' => 'localhost' /* Or maybe IP address of your database server */
);
PHPCache::configure($database);
$cache = PHPCache::instance();
if( ($results = $cache->get('result_of_some_nasty_code')) !== false ) {
$tpl->assign($results);
/* Or maybe return $results or whatever depending on where you use this */
} else {
/***********************
* Your slow code here
***********************/
$cache->store('result_of_some_nasty_code', $results_of_your_slow_code, PHPCACHE_1_HOUR * 5); /* Cache for 5 hours */
}
It’s very simple!
You can use it in any kind of application, commercial and non-commercial, the only thing I ask is that if you like it, help me spread the word.
You can write a blog post about it, tell your friends about it or whatever, I will really appreciate that
What you can store
You can store variables, arrays and objects BUT not resources (like a file or a database handle), PHPCache will serialize your array or object for you but remember to read the information on this page regarding object unserialization:
http://us3.php.net/unserialize
Date constants
PHPCACHE_1_SECOND
PHPCACHE_1_MINUTE
PHPCACHE_1_HOUR
PHPCACHE_1_DAY
PHPCACHE_1_WEEK
PHPCACHE_1_MONTH
PHPCACHE_1_YEAR
To store something for 5 days:
$cache->store('user_' .$user_id, $results_of_your_slow_code, PHPCACHE_1_DAY * 5);
How fast is it?
It can handle 2,300 queries per second on SQLite and 2,500 on MySQL. That’s very fast…
What about user specific data?
If your website has members and you want to cache some data specific to a user you can do something like this:
$cache->store('user_' .$user_id, $results_of_your_slow_code, PHPCACHE_1_MINUTE * 5);
What about the database table?
You don’t need to create the database table for PHPCache, the only thing you need to do is to populate this array:
$database = array(
'type' => 'mysql',
'name' => 'YOUR DATABASE NAME',
'table' => 'PHPCache',
'user' => 'YOUR DATABASE USERNAME',
'pass' => 'YOUR DATABASE USERNAME\'S PASSWORD',
'host' => 'localhost' /* Or maybe IP address of your database server */
);
Or for SQLite:
$database = array(
'type' => 'sqlite',
'name' => 'PATH TO A DATABASE FILE',
'table' => 'PHPCache'
);
“The filename (which is the name in our $database array) of the SQLite database. If the file does not exist, SQLite will attempt to create it. PHP must have write permissions to the file if data is inserted, the database schema is modified or to create the database if it does not exist.”
You can read more about SQLite here:
http://us3.php.net/manual/en/book.sqlite.php
After you setup the $database array you can go ahead and configure PHPCache like this:
PHPCache::configure($database);
Then you can ask PHPCache to make the table for you:
$cache = PHPCache::instance();
$cache->create_table();
Remeber to call $cache->create_table(); only once the first time you use PHPCache!
Also remember, when using SQLite, PHP must have write permissions to the directory you want to make the database file in, for example if you have:
$database = array(
'type' => 'sqlite',
'name' => $_SERVER['DOCUMENT_ROOT'] .'/cache/phpcache_database_file',
'table' => 'PHPCache'
);
You must create the directory “cache” and change it’s permissions so PHP can write to it.
How to write a driver for it?
Here is the interface your driver should implement:
interface PHPCache_Driver_Interface {
public function query($query);
public function escape($value);
public function close();
public function error();
public function create_table($table_name);
}
interface PHPCache_Driver_Results_Interface {
public function fetch_row();
public function fetch_array();
public function fetch_assoc();
}
Suppose you want to write a driver for MSSQL, then you will have to write two classes and place them in a file named “phpcache.driver.mssql.class.php” and move it to the folder “PHPCache/drivers”.
Your class names should follow these rules:
class PHPCache_Driver_mssql implements PHPCache_Driver_Interface {
/* ... */
} // Class
class PHPCache_Driver_mssql_Results implements PHPCache_Driver_Results_Interface {
/* ... */
} // Class
Then you can use your driver like this:
$database = array(
'type' => 'mssql',
'name' => 'YOUR DATABASE NAME',
'table' => 'PHPCache',
'user' => 'YOUR DATABASE USERNAME',
'pass' => 'YOUR DATABASE USERNAME\'S PASSWORD',
'host' => 'localhost' /* Or maybe IP address of your database server */
);
Take a look at one of the drivers to see how exactly it looks like.
EDIT 9/15/2008:
A new version of PHPCache is available.
This one has 5 new methods:
PHPCache::set_expire($key)
Which will set the expiration of the cache record for $key in the past, I think this method has some advantages over deleting the key all together.
PHPCache::remove($key)
Will completely remove the row.
PHPCache::clean_up()
This method will be called when ever you construct/configure a new PHPCache object with PHPCache::configure($database) method and does two things:
1 - Will delete all the old keys on the table, you can control how often this happens with 2 constants:
PHPCACHE_GC_PROBABILITY & PHPCACHE_GC_DIVISOR
If you set PHPCACHE_GC_PROBABILITY to 10 and PHPCACHE_GC_DIVISOR to 100, then when ever you configure the PHPCache object with PHPCache::configure($database); there will be 10% chance that the garbage collector will delete the old rows.
The default value is 1%.
2 - It will optimize the table PHPCache is using, you can also control how often this happens through 2 other constants:
PHPCACHE_TO_PROBABILITY & PHPCACHE_TO_DIVISOR
It works similar to #1 and default value is 10%.
PHPCache::gc()
Will delete the old rows anytime you call this method, it doesn’t care about PHPCACHE_GC_PROBABILITY & PHPCACHE_GC_DIVISOR
One place to use this would be a cron tab.
PHPCache::optimize_table()
Will optimize PHPCache’s table and doesn’t care about
PHPCACHE_TO_PROBABILITY & PHPCACHE_TO_DIVISOR
This new version has some more minor improvements over the old one too.