NotionCommotion Posted February 3, 2015 Share Posted February 3, 2015 (edited) EDIT. When starting this post, I thought it was causing the browser to make an extra request to the server. I've since found this wasn't the case, however, didn't change the title of this post, and can't seem to change it to something like "Critique of file caching script" I am trying to cache a file, and put together the following script. I put the following in the browser: https://test.sites.example.com/administrator/index.php?cid=2&controller=sell&id=643341356 ... and Apache will rewrite as: https://test.sites.example.com/index.php?admin=administrator&cid=2&controller=sell&id=643341356 index.php includes the following line: <script src="/lib/js/clientConstants.php?b=1" type="text/javascript"> I know I am asking a lot, but would appreciate if someone could review the below code and give me opinions or custructive critism. One thing I noticed is the check to see if the client should use its local cached file never gets executed by the server. Maybe modern browsers just "know" when they don't need to request a copy from the server? Thank you /lib/js/clientConstants.php <?php require_once(dirname(dirname(dirname(__DIR__))).'/application/classes/cache.php'); $cache=new cache(__FILE__); $cache->content_type="text/javascript"; $cache->callback=function($root) { echo('some text from the database'); }; $cache->invoke(); ?> /application/classes/cache.php <?php class cache { public $cacheDir='/var/www/cache/'; //Where to cache /** * Default content type * @var string */ public $content_type="text/html"; /** * Default time to cache equal to 60*60*24*12 * @var string */ public $cachetime=1036800; /** * $callback * @var string */ public $callback; /** * File to cache * @var string */ private $originalfile; /** * $cachefile * @var string */ private $cachefile; /** * __construct to store in $this */ public function __construct($file) { $this->originalfile=$file; } /** * If file doesn't exist, create file. Download the file */ public function invoke() { date_default_timezone_set('UTC'); //Be sure info from client is okay $this->cachefile = (strpbrk(basename($_SERVER['REQUEST_URI']), "\\/%*:|\"<>") === FALSE)?$this->cacheDir.basename($_SERVER['REQUEST_URI']):null; $fileExists=file_exists($this->cachefile); $filetime=filemtime($fileExists?$this->cachefile:$this->originalfile); if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $filetime)) { //Use file on client syslog(LOG_DEBUG,'Use cached file on client'); header('Last-Modified: '.gmdate('D, d M Y H:i:s', $filetime).' GMT', true, 304); } else { //Not yet cached on client header( 'Content-type: '.$this->content_type); header('Pragma: public'); header('Cache-Control: public, maxage='.$this->cachetime); header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$this->cachetime) . ' GMT'); header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($this->originalfile)).' GMT', true, 200); if ($fileExists && (time() - $this->cachetime < filemtime($this->cachefile))) { // Serve from the cache if it exists and is younger than $cachetime syslog(LOG_DEBUG,'Use cached file on server'); include($this->cachefile); switch($this->content_type) { case 'text/html': echo "<!-- Cached ".date('jS F Y H:i', filemtime($cachefile))." -->";break; case 'text/javascript': echo "/* Cached ".date('jS F Y H:i', filemtime($this->cachefile))." */";break; //No comments for other file types } } else { //create new file ob_start(); //Pass web directory to call back if it needs it call_user_func($this->callback,dirname(dirname(__DIR__))); syslog(LOG_DEBUG,"create new cache file"); $fp = fopen($this->cachefile, 'w'); // open the cache file for writing fwrite($fp, ob_get_contents()); // save the contents of output buffer to the file fclose($fp); ob_end_flush(); // Send the output to the browser } } } } ?> Edited February 3, 2015 by NotionCommotion Quote Link to comment Share on other sites More sharing options...
scootstah Posted February 3, 2015 Share Posted February 3, 2015 You might find that you have better luck using an HTTP proxy such as Varnish. The way you are caching, the request still has to be processed by Apache, and execute PHP code. But with something like Varnish it will never even get to Apache. You can even configure it so that the cache stays in memory, and then it won't even hit the disk. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted February 3, 2015 Author Share Posted February 3, 2015 Thanks scootstah, Does Varnish seem to do a good job knowing which files should be cached? Quote Link to comment Share on other sites More sharing options...
scootstah Posted February 4, 2015 Share Posted February 4, 2015 I believe by default it caches all responses. But, you can configure exactly which URL's you want to cache for. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.