2008-03-18, 04:01 AM
Hi everyone, I'm looking for some feedback from some fellow PHP developers.
First off, let me say that I am very focused on efficiency, specifically minimizing the bandwidth footprint, processing time, and memory size of my website. I have multiple services that run on a single server that constantly use bandwidth and processing power, so everything needs to be optimized.
Now, let's get to the problem. For my main page, I have created a custom script that pulls threads and comments from a specific forum. These display as "News". Now, the query that is used to pull this information from MySQL is rather complex, consisting of multiple JOINs. This page needs to be cached, since preforming this query every time someone visits the site or reloads the news page is highly inefficient, as the news does not change very often. Now, the traditional way to solve this is just have a cache that expires in a few minutes. However, due to the low traffic of my site currently, having the cache expire every few minutes would do little good. Also, setting the expiration time too high would be counter-intuitive, since the "News" will be old.
So, this was my quandary. I needed a cache that only expires when it needs to expire, when the news forum changes.
To do this, I have created a MyBB plugin. It hooks into the various features of MyBB (specifically, the new thread, new reply, and moderation functions), which allows it to delete the cache file once something in the news forum gets changed. (I'll include the plugin code at the end of this post as a reference or for anyone that might need it.)
However, something still doesn't seem right. I can't explain it, but the solution seems "off". So, that's why I have posted here, to get some more eyes to take a look at my solution and give feedback.
Thanks in advance, everyone.
Here's the Plugin Code:
mecache.php
First off, let me say that I am very focused on efficiency, specifically minimizing the bandwidth footprint, processing time, and memory size of my website. I have multiple services that run on a single server that constantly use bandwidth and processing power, so everything needs to be optimized.
Now, let's get to the problem. For my main page, I have created a custom script that pulls threads and comments from a specific forum. These display as "News". Now, the query that is used to pull this information from MySQL is rather complex, consisting of multiple JOINs. This page needs to be cached, since preforming this query every time someone visits the site or reloads the news page is highly inefficient, as the news does not change very often. Now, the traditional way to solve this is just have a cache that expires in a few minutes. However, due to the low traffic of my site currently, having the cache expire every few minutes would do little good. Also, setting the expiration time too high would be counter-intuitive, since the "News" will be old.
So, this was my quandary. I needed a cache that only expires when it needs to expire, when the news forum changes.
To do this, I have created a MyBB plugin. It hooks into the various features of MyBB (specifically, the new thread, new reply, and moderation functions), which allows it to delete the cache file once something in the news forum gets changed. (I'll include the plugin code at the end of this post as a reference or for anyone that might need it.)
However, something still doesn't seem right. I can't explain it, but the solution seems "off". So, that's why I have posted here, to get some more eyes to take a look at my solution and give feedback.
Thanks in advance, everyone.
Here's the Plugin Code:
mecache.php
<?php
/*
Plugin By: Blue
http://community.mybboard.net/member.php?action=profile&uid=671
*/
if(!defined('IN_MYBB'))
{
die('Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.');
}
$plugins->add_hook('newreply_do_newreply_end', 'mecache_newreply');
$plugins->add_hook('newthread_do_newthread_end', 'mecache_newthread');
$plugins->add_hook('moderation_stick', 'mecache_moderation');
$plugins->add_hook('moderation_multistickthreads', 'mecache_moderation');
$plugins->add_hook('moderation_multiunstickthreads', 'mecache_moderation');
$plugins->add_hook('moderation_do_deletethread', 'mecache_moderation');
$plugins->add_hook('moderation_do_multideletethreads', 'mecache_moderation');
$plugins->add_hook('moderation_do_deleteposts', 'mecache_moderation');
$plugins->add_hook('moderation_do_multideleteposts', 'mecache_moderation');
$plugins->add_hook('admin_index_navigation_end', 'mecache_adminnavigation');
$plugins->add_hook('admin_maintenance_start', 'mecache_adminupdate');
/*
General Functions
*/
function mecache_info()
{
return array(
'name' => 'News Cache Updater',
'description' => 'Updates the news front page cache on new posts in news forum.',
'website' => '',
'author' => 'Blue',
'authorsite' => '',
'version' => '1.0',
);
}
function mecache_activate()
{
global $db;
$group = array(
"gid" => "NULL",
"title" => "News Cache Updater",
"name" => "mecache",
"description" => "Settings for News Cache Updater system.",
"disporder" => "20",
"isdefault" => "no"
);
$db->insert_query(TABLE_PREFIX."settinggroups", $group);
$gid = $db->insert_id(); //This will get the id of the just added record in the db
$newsetting1 = array(
'name' => 'mecachefid',
'title' => 'Forum ID',
'description' => 'Insert the forum id of the news forum.',
'optionscode' => 'text',
'value' => '',
'disporder' => 1,
'gid' => $gid
);
$db->insert_query(TABLE_PREFIX.'settings', $newsetting1);
$newsetting2 = array(
'name' => 'mecachepath',
'title' => 'Cache Path',
'description' => 'Insert the full path to the cache folder.',
'optionscode' => 'text',
'value' => '',
'disporder' => 2,
'gid' => $gid
);
$db->insert_query(TABLE_PREFIX.'settings', $newsetting2);
$newsetting3 = array(
'name' => 'mecacheid',
'title' => 'Cache ID',
'description' => 'The file name of the cache file.',
'optionscode' => 'text',
'value' => '',
'disporder' => 3,
'gid' => $gid
);
$db->insert_query(TABLE_PREFIX.'settings', $newsetting3);
rebuildsettings();
}
function mecache_deactivate()
{
global $db;
$db->query('DELETE FROM '.TABLE_PREFIX.'settings WHERE name=\'mecachefid\' OR name=\'mecachepath\' OR name=\'mecacheid\'');
$db->query('DELETE FROM '.TABLE_PREFIX.'settinggroups WHERE name=\'mecache\'');
rebuildsettings();
}
/*
End General Functions
Plugin Hook Functions
*/
function mecache_newreply()
{
global $post, $mybb;
if(!empty($mybb->settings['mecachefid']) && !empty($mybb->settings['mecachepath'])
&& !empty($mybb->settings['mecacheid']) && $post['fid'] == $mybb->settings['mecachefid'])
{
if(file_exists($mybb->settings['mecachepath'] . $mybb->settings['mecacheid'])) {
unlink($mybb->settings['mecachepath'] . $mybb->settings['mecacheid']);
}
}
}
function mecache_newthread()
{
global $new_thread, $mybb;
if(!empty($mybb->settings['mecachefid']) && !empty($mybb->settings['mecachepath'])
&& !empty($mybb->settings['mecacheid']) && $new_thread['fid'] == $mybb->settings['mecachefid'])
{
if(file_exists($mybb->settings['mecachepath'] . $mybb->settings['mecacheid'])) {
unlink($mybb->settings['mecachepath'] . $mybb->settings['mecacheid']);
}
}
}
function mecache_moderation()
{
global $fid, $mybb;
if(!empty($mybb->settings['mecachefid']) && !empty($mybb->settings['mecachepath'])
&& !empty($mybb->settings['mecacheid']) && $fid == $mybb->settings['mecachefid'])
{
if(file_exists($mybb->settings['mecachepath'] . $mybb->settings['mecacheid'])) {
unlink($mybb->settings['mecachepath'] . $mybb->settings['mecacheid']);
}
}
}
function mecache_adminnavigation()
{
global $menu;
$menu[10]['items'][100] = array("title" => "Rebuild News Cache", "url" => "maintenance.php?".SID."&action=rebuildfnc");
}
function mecache_adminupdate()
{
global $mybb;
if($mybb->input['action'] == 'rebuildfnc')
{
if(file_exists($mybb->settings['mecachepath'] . $mybb->settings['mecacheid'])) {
unlink($mybb->settings['mecachepath'] . $mybb->settings['mecacheid']);
}
cpredirect("index.php?".SID."&action=home", "The front page news cache has been updated.");
}
}
/*
End Plugin Hook Functions
*/
?>