Return to Snippet

Revision: 31308
at September 2, 2010 16:57 by Sverri


Initial Code
// css.php

/*
  If you name this file "css.php" then you can call it
  using a GET query string like this:
  
  - css.php?files=reset,style,iefix&minify=yes
  
  There are two parts to the query string:
  
  1. The "files" part. Add your file names (with or
     without .css) in a comma-separated list.
  
  2. The "minify" part. You can add "yes" to it, or
     omit it entirely.
  
  When you have done this and loaded the file once the
  script will cache, update, serve files and handle
  everything else. You only have to specify which files
  should be loaded and if it should be minified.
  
  The script will automatically update the cached files
  whenever they become outdated, so you can edit your
  individual CSS files as much as you like without
  worrying about getting the most recent file.
*/


// Handle the query string

if (isset($_GET['files']) && !empty($_GET['files'])) {
  $files = explode(',', strip_tags($_GET['files']));
} else {
  $files = null;
}
if (isset($_GET['minify']) && !empty($_GET['minify'])) {
  $minify = (strip_tags($_GET['minify'])=='yes') ? true : false;
} else {
  $minify = false;
}

// Get the file names

$filesMissing = 0;
foreach ($files as $key => &$name) {
  $name = trim($name);
  if (empty($name)) {
    unset($files[$key]);
    continue;
  }
  if (substr($name,-4) !== '.css') {
    $name .= '.css';
  }
  if ( ! file_exists($name)) {
    $filesMissing++;
  }
  $dates[] = filemtime($name);
}

// If there are no file names, or if a file does not exist
// then 404; Houston we have a problem...

if (empty($files) || $filesMissing > 0) {
  header("HTTP/1.0 404 Not Found");
  exit();
}

// Is there a cached version and is it newer than the non-cached
// files? If there is one then go directly to output

// !!! Make sure the directory "cached" is writeable !!!

$cachedFileName = 'cached/'.crc32(implode('.',$files)).($minify?'.min':'').'.css';
$useCache = false;

if (file_exists($cachedFileName)) {
  $cachedLastModified = filemtime($cachedFileName);
  foreach ($dates as $d) {
    if ($cachedLastModified < $d) { $useCache = false; break; }
  }
  if ($useCache) {
    $code = file_get_contents($cachedFileName);
    goto output;
  }
}

// If there is no cached version, or if the cached version is older
// than the css files, then get the code from the css files and save a
// cached version for future use

$code = '';
foreach ($files as $name) {
  $code .= file_get_contents($name)."\n\n";
}
if ($minify) {
  $code = minifyCSS($code);
}
$f = fopen($cachedFileName, 'w');
fwrite($f, $code);
fclose($f);
$cachedLastModified = filemtime($cachedFileName);

// The output

output:
{
  header('Content-type: text/css; charset=utf-8');
  header('Last-Modified: '.gmdate('D, d M Y H:i:s',$cachedLastModified).' GMT');
  header('Expires: '.gmdate('D, d M Y H:i:s', time()+604800).' GMT'); // 1 week
  header('Cache-Control: max-age=604800'); // 1 week
  $encoding = false;
  $httpEncoding = strip_tags($_SERVER['HTTP_ACCEPT_ENCODING']);
  if(strpos($httpEncoding, 'x-gzip') !== false) {
    $encoding = 'x-gzip';
  }
  elseif(strpos($httpEncoding, 'gzip') !== false) {
    $encoding = 'gzip';
  }
  if ($encoding) {
    header('Content-Encoding: '.$encoding);
    $code = gzcompress($code, 9);
  }
  echo $code;
}

// Function for minifying CSS code
// Removes or truncates unecessary characters, whitespace and newlines
function minifyCSS($code) {
  return preg_replace(array('/\/\*[\s\S]*?\*\//','/\s*([;:{},>+])\s*/','/(;})/',
  '/\r?\n/','/\t/'),array('','\1','}','',''),$code);
}

Initial URL

                                

Initial Description
The code is not particularly pretty but it does the job.

If you call this file css.php you can call it like this:

css.php?files=reset,style,iefix&minify=yes

Initial Title
Combine and minify CSS using get query string

Initial Tags
css

Initial Language
PHP