<?php
// Written by Ed Eliot (www.ejeliot.com) - provided as-is, use at your own risk
//This script was modified by Mihalcea Romeo from roscripts.com in order to output a more compressed file without touching the original files used.
//
/****************** start of config ******************/
define('FILE_TYPE', 'text/css'); // type of code we're outputting
define('CACHE_LENGTH', 31356000); // length of time to cache output file, default approx 1 year
define('CREATE_ARCHIVE', true); // set to false to suppress writing of code archive, files will be merged on each request
define('ARCHIVE_FOLDER', 'cache'); // location to store archive, don't add starting or trailing slashes. Remember to CHMOD this to 0777
// files to merge
$aFiles = array(
'css/your_css_file_here.css',
'css/your_css_file_here1.css',
'css/your_css_file_here2.css',
'css/your_css_file_here3.css',
'css/your_css_file_here4.css',
'css/your_css_file_here5.css',
'css/your_css_file_here6.css',
'css/your_css_file_here7.css'
);
/****************** end of config ********************/
// this is prepended to all file / folder paths so files and archive folder should be specified relative to this
$sDocRoot = $_SERVER['DOCUMENT_ROOT'];
/*
if etag parameter is present then the script is being called directly, otherwise we're including it in
another script with require or include. If calling directly we return code othewise we return the etag
representing the latest files
*/
if (isset($_GET['version'])) {
$iETag = (int)$_GET['version'];
$sLastModified = gmdate('D, d M Y H:i:s', $iETag).' GMT';
// see if the user has an updated copy in browser cache
if (
(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $sLastModified) ||
(isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $iETag)
) {
header("{$_SERVER['SERVER_PROTOCOL']} 304 Not Modified");
exit;
}
// create a directory for storing current and archive versions
if (CREATE_ARCHIVE && !is_dir("$sDocRoot/".ARCHIVE_FOLDER)) {
mkdir("$sDocRoot/".ARCHIVE_FOLDER);
}
// get code from archive folder if it exists, otherwise grab latest files, merge and save in archive folder
if (CREATE_ARCHIVE && file_exists("$sDocRoot/".ARCHIVE_FOLDER."/$iETag.cache")) {
$sCode = file_get_contents("$sDocRoot/".ARCHIVE_FOLDER."/$iETag.cache");
} else {
// get and merge code
$sCode = '';
$aLastModifieds = array();
foreach ($aFiles as $sFile) {
$aLastModifieds[] = filemtime("$sDocRoot/$sFile");
$sCode .= file_get_contents("$sDocRoot/$sFile");
}
// sort dates, newest first
rsort($aLastModifieds);
if (CREATE_ARCHIVE) {
if ($iETag == $aLastModifieds[0]) { // check for valid etag, we don't want invalid requests to fill up archive folder
$oFile = fopen("$sDocRoot/".ARCHIVE_FOLDER."/$iETag.cache", 'w');
if (flock($oFile, LOCK_EX)) {
fwrite($oFile, compress($sCode));
flock($oFile, LOCK_UN);
}
fclose($oFile);
} else {
// archive file no longer exists or invalid etag specified
header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found");
exit;
}
}
}
// send HTTP headers to ensure aggressive caching
header('Expires: '.gmdate('D, d M Y H:i:s', time() + CACHE_LENGTH).' GMT'); // 1 year from now
header('Content-Type: '.FILE_TYPE);
header('Content-Length: '.strlen($sCode));
header("Last-Modified: $sLastModified");
header("ETag: $iETag");
header('Cache-Control: max-age='.CACHE_LENGTH);
// output merged code
ob_start("compress");
echo $sCode;
ob_end_flush();
} else {
// get file last modified dates
$aLastModifieds = array();
foreach ($aFiles as $sFile) {
$aLastModifieds[] = filemtime("$sDocRoot/$sFile");
}
// sort dates, newest first
rsort($aLastModifieds);
// output latest timestamp
echo $aLastModifieds[0];
}
function compress($buffer) {
// remove comments
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
// remove tabs, spaces, newlines, etc.
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);
return $buffer;
}
?>
Example usage:
<link href="cache/site_<?php require('compressor.php'); ?>.css" rel="stylesheet" type="text/css" />
<!--
cache = the folder used for saving the created files
compressor.php = this is the name of the file above presented that will compress the code and also combine our files into a single one.
-->
A friend of mine told me an interesting thing. What if I use some files for some pages only and not in all my pages. This script will combine them all together but in many pages the code will never be used. No problemo. Here we get a little more complicated.
If we look at the code we have the following array:
// files to merge
$aFiles = array(
'css/your_css_file_here.css',
'css/your_css_file_here1.css',
'css/your_css_file_here2.css',
'css/your_css_file_here3.css',
'css/your_css_file_here4.css',
'css/your_css_file_here5.css',
'css/your_css_file_here6.css',
'css/your_css_file_here7.css'
);
This is the part where we tell the script what files to use and compress. Let's say we have two pages. One called index.php where we want to use all the css files and one called something.php where we want to use only the first two css files. How do we do that?
Here's for that how question. We will use the "eregi" function from PHP to define some conditional statements (here's a full article on conditional statements and how to use them). We will create an example based on our needs.
if (eregi("index.php", $_SERVER['PHP_SELF']) {
$aFiles = array(
'css/your_css_file_here.css',
'css/your_css_file_here1.css',
'css/your_css_file_here2.css',
'css/your_css_file_here3.css',
'css/your_css_file_here4.css',
'css/your_css_file_here5.css',
'css/your_css_file_here6.css',
'css/your_css_file_here7.css'
);
} elseif (eregi("something.php", $_SERVER['PHP_SELF']) {
$aFiles = array(
'css/your_css_file_here.css',
'css/your_css_file_here7.css'
);
}
Notice we used "elseif" in order to specify the other case where we will use a different array for "something.php" but we could leave it as just "else" and in this case the array will contain all the scripts for "index.php" but just the first two for the rest of our pages.
The last thing that we need to do is to modify out .htaccess file to tell our server where to look for the new CSS and JS files so we will create a small rule to be followed.
RewriteEngine On
RewriteBase /
RewriteRule cache/site_([0-9]+).css compressor.php?version=$1 [L]
RewriteRule cache/site_([0-9]+).js compressor_js.php?version=$1 [L]
Notice that I've used two files. "compress.php" for the css files and "compress_js.php" for javascript.
Thank you for reading this,
Mihalcea Romeo
Added by roScripts on April-18-2007, 3:53 pm
