Jump to content

Caching files cause extra server hit.


NotionCommotion

Recommended Posts

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 by NotionCommotion
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.