Also View In:
ASP.NET

Tutorial: How to Implement Autoversioning in PHP Without .htaccess


Example Markup
<link rel="stylesheet" type="text/css" href="<?php echo auto_version('/css/default.css'); ?>" />
			
Example Code Behind
$ROOT = ''; //production environment root
//$ROOT = '/phpJMcConahie'; //dev environment root
	
//appends a version number to the end of css and js files
function auto_version($filename)
{
    global $ROOT;

    //verify file exists
    $filepath = realpath(dirname(__FILE__) . $filename);
    if(!file_exists($filepath))
    {
        return $filename . '?ver=noexist';
    }
	
    //get last modified date of file to use as version number
    $mtime = filemtime($filepath);
	
    //make filename relative to website's root directory 
    //this is useful for dev environments 
    $filename = $ROOT . $filename;
	
    //append version number to end of filename
    if(Str_Ends_With($filename, '.css'))
    {
        return str_replace('.css', '.css?ver=' . $mtime, $filename);
    }
    else if(Str_Ends_With($filename, '.js'))
    {
        return str_replace('.js', '.js?ver=' . $mtime, $filename);
    }
	
    return $filename . '?ver=ExtensionNotSupported';
}

//returns true if string ends with search string, false otherwise.
//returns false for any passed empty strings
//not case-sensitive
function Str_Ends_With($string, $searchString)
{
    //normalize character case
    $string = strtolower($string);
    $searchString = strtolower($searchString);

    //get string lengths
    $strLen = strlen($string);
    $searchLen = strlen($searchString);
	
    //make sure each string is at least 1 character long
    if($strLen > 0 && $searchLen > 0)
    {
        //search string must be smaller than starting string
        if($searchLen <= $strLen)
        {
            //use string length difference as starting point
            $difference = $strLen - $searchLen;
			
            //get substring from starting point equal to length of searchstring
            $compareString = substr($string, $difference, $searchLen);
			
            //if substring equals search string, then the string ends with search string
            if($compareString == $searchString)
            {
                return true;
            }
        }
    }
	
    return false;
}
			

Published: April 15, 2015

Author's Notes: For ease of use, put the code behind in a file that's included on every page. This way, you only have to change the $ROOT variable once when moving from dev to production. You can remove the $ROOT variable entirely if there is no difference between your development and production root folders.

The Str_Ends_With() function could probably be rewritten to be more streamlined. I didn't like any versions of it that I found on the web, so I just wrote one I knew worked for simple file naming schemes.

CSS and JS file paths should be root relative with a leading '/'. Note that this is different from the ASP.NET example.