Adding Zend_Cache to Flex/Flash Builder 4 Projects

I have som rather large and time con­sum­ing queries run­ning in the Sta­tis­tics screen of an NOC (Net­work Oper­a­tions Cen­ter) Flex/Flash Builder 4 appli­ca­tion i’we been tin­ker­ing with, to pre­vent the data­base server to be boggen down by mul­ti­ple queries fired by this app in mul­ti­ple places I had to imple­ment caching.

And to do this is alot eas­ier than it might sound like espe­cially for the (PHP) Zend_AMF based services.

Once you have setup your Data Cen­tric client/server  con­nec­tion like it’s described in this Arti­cle @ Dev­Zone you begin by edit­ing the gateway.php;

// Store configuration in the registry
Zend_Registry::set("amf-config", $amf);

// Con­fig­ure Zend_Cache
$fron­tendOp­tions = array(
‘life­time’ => 12*3600,
‘automatic_serialization’ => true,
‘default_options’ => array(
‘cache_with_get_variables’ => true,
‘cache_with_post_variables’ => true,
‘cache_with_session_variables’ => true,
‘cache_with_files_variables’ => true,
‘cache_with_cookie_variables’ => true,
‘make_id_with_get_variables’ => true,
‘make_id_with_post_variables’ => true,
‘make_id_with_session_variables’ => true,
‘make_id_with_files_variables’ => true,
‘make_id_with_cookie_variables’ => true
)
);
$back­endOp­tions = array(
‘cache_dir’ => ‘/tmp/‘
);

$cache = Zend_Cache::factory(‘Core’, ‘File’, $fron­tendOp­tions, $backendOptions);

// Store cache con­fig­u­ra­tion in the reg­istry
Zend_Registry::set(“cache”, $cache);

Then mod­ify your ser­vice class to look sim­i­lar to this;

public function getCustomerStatsByMonth() {
// Get the Cache from Registry
$cache = Zend_Registry::get("cache");
$id = 'getCustomerStatsByMonth';
if(!($rows = $cache->load($id)))
{
// We didnt find anything in the cache so lets get it from DB
$stmt = mysqli_prepare($this->connection, "SELECT
customers.name,
SUBSTR(FROM_UNIXTIME(`cdrs`.`start`),1,7) AS `month`,
outgroups.name_invoices,
ROUND(SUM(`cdrs`.`talktime`)/60) AS `minutes`,
COUNT(`cdrs`.`start`) AS `calls`
FROM
es.outgroups
INNER JOIN es.cdrs
ON (outgroups.id = cdrs.outgroup)
INNER JOIN es.customers
ON (customers.id = cdrs.scustomer)
WHERE (outgroups.name_invoices LIKE 'Sweden%' AND cdrs.start > UNIX_TIMESTAMP('2010-01-01 00:00:00') AND cdrs.status = 'answer' AND cdrs.talktime > 0 AND custome\
rs.parent IN (7,42))
GROUP BY customers.id,SUBSTR(FROM_UNIXTIME(`cdrs`.`start`),1,7),outgroups.name_invoices
ORDER BY SUBSTR(FROM_UNIXTIME(`cdrs`.`start`),1,7),outgroups.name_invoices;");
$this->throwExceptionOnError();

mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();

$rows = array();

mysqli_stmt_bind_result($stmt, $row->name, $row->month, $row->name_invoices, $row->minutes, $row->calls);

while (mysqli_stmt_fetch($stmt)) {
$row->month = new DateTime($row->month.’-01 00:00:00′);
$rows[] = $row;
$row = new std­Class();
mysqli_stmt_bind_result($stmt, $row->name, $row->month, $row->name_invoices, $row->minutes, $row->calls);
}

mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
// Save col­lected rows into the cache
$cache->save($rows,$id,array(‘customer_stats’),3*3600);
}
return $rows;
}

Your queries will now be cached after the first time you run them for the spec­i­fied amount of time (TTL), and boom you’re done. If you require the update func­tion in your ser­vice classes to purge the cache sim­ply insert;

// To remove or invalidate in particular cache id, you can use the remove() method :
$cache->remove('idToRemove');

Read more about cache clean­ing in the Zend Cache reference.

Hope this lit­tle arti­cle helps and please com­ment if you guys have bet­ter sug­ges­tions.
(Yes I know I can use APC & Mem­cached, but in this exam­ple I didnt have to :) )

Regards
Danny Froberg

Leave a Comment

*

Get Adobe Flash playerPlugin by wpburn.com wordpress themes