| // | Allan Hansen | // +----------------------------------------------------------------------+ // | extension.cache.mysql.php | // | MySQL Cache Extension. | // | dependencies: getid3. | // +----------------------------------------------------------------------+ // // $Id: extension.cache.dbm.php 3318 2009-05-20 21:54:10Z vdigital $ /** * This is a caching extension for getID3(). It works the exact same * way as the getID3 class, but return cached information very fast * * Example: (see also demo.cache.dbm.php in /demo/) * * Normal getID3 usage (example): * * require_once 'getid3/getid3.php'; * $getid3 = new getid3; * $getid3->encoding = 'UTF-8'; * try { * $info1 = $getid3->Analyse('file1.flac'); * $info2 = $getid3->Analyse('file2.wv'); * .... * * getID3_cached usage: * * require_once 'getid3/getid3.php'; * require_once 'getid3/getid3/extension.cache.mysql.php'; * $getid3 = new getid3_cached_mysql('localhost', 'database', 'username', 'password'); * $getid3->encoding = 'UTF-8'; * try { * $info1 = $getid3->analyse('file1.flac'); * $info2 = $getid3->analyse('file2.wv'); * ... * * * Supported Cache Types * * SQL Databases: (use extension.cache.mysql) * * cache_type cache_options * ------------------------------------------------------------------- * mysql host, database, username, password * * * DBM-Style Databases: (this extension) * * cache_type cache_options * ------------------------------------------------------------------- * gdbm dbm_filename, lock_filename * ndbm dbm_filename, lock_filename * db2 dbm_filename, lock_filename * db3 dbm_filename, lock_filename * db4 dbm_filename, lock_filename (PHP5 required) * * PHP must have write access to both dbm_filename and lock_filename. * * * Recommended Cache Types * * Infrequent updates, many reads any DBM * Frequent updates mysql */ class getid3_cached_dbm extends getid3 { public function __construct($cache_type, $dbm_filename, $lock_filename) { // Check for dba extension if (!extension_loaded('dba')) { throw new getid3_exception('PHP is not compiled with dba support, required to use DBM style cache.'); } if (!in_array($cache_type, dba_handlers())) { throw new getid3_exception('PHP is not compiled --with '.$cache_type.' support, required to use DBM style cache.'); } // Create lock file if needed if (!file_exists($lock_filename)) { if (!touch($lock_filename)) { die('failed to create lock file: ' . $lock_filename); } } // Open lock file for writing if (!is_writeable($lock_filename)) { die('lock file: ' . $lock_filename . ' is not writable'); } $this->lock = fopen($lock_filename, 'w'); // Acquire exclusive write lock to lock file flock($this->lock, LOCK_EX); // Create dbm-file if needed if (!file_exists($dbm_filename)) { if (!touch($dbm_filename)) { die('failed to create dbm file: ' . $dbm_filename); } } // Try to open dbm file for writing $this->dba = @dba_open($dbm_filename, 'w', $cache_type); if (!$this->dba) { // Failed - create new dbm file $this->dba = dba_open($dbm_filename, 'n', $cache_type); if (!$this->dba) { die('failed to create dbm file: ' . $dbm_filename); } // Insert getID3 version number dba_insert(getid3::VERSION, getid3::VERSION, $this->dba); } // Init misc values $this->cache_type = $cache_type; $this->dbm_filename = $dbm_filename; // Register destructor register_shutdown_function(array($this, '__destruct')); // Check version number and clear cache if changed if (dba_fetch(getid3::VERSION, $this->dba) != getid3::VERSION) { $this->clear_cache(); } parent::__construct(); } public function __destruct() { // Close dbm file @dba_close($this->dba); // Release exclusive lock @flock($this->lock, LOCK_UN); // Close lock file @fclose($this->lock); } public function clear_cache() { // Close dbm file dba_close($this->dba); // Create new dbm file $this->dba = dba_open($this->dbm_filename, 'n', $this->cache_type); if (!$this->dba) { die('failed to clear cache/recreate dbm file: ' . $this->dbm_filename); } // Insert getID3 version number dba_insert(getid3::VERSION, getid3::VERSION, $this->dba); // Reregister shutdown function register_shutdown_function(array($this, '__destruct')); } // public: analyze file public function Analyze($filename) { if (file_exists($filename)) { // Calc key filename::mod_time::size - should be unique $key = $filename . '::' . filemtime($filename) . '::' . filesize($filename); // Loopup key $result = dba_fetch($key, $this->dba); // Hit if ($result !== false) { return unserialize($result); } } // Miss $result = parent::Analyze($filename); // Save result if (file_exists($filename)) { dba_insert($key, serialize($result), $this->dba); } return $result; } } ?>