Shoora
11/7/2013 - 12:08 PM

PHP Minify ( http://code.google.com/p/minify ) post-processing helper class to replace small CSS images with inline data. This decreases nu

PHP Minify ( http://code.google.com/p/minify ) post-processing helper class to replace small CSS images with inline data. This decreases number of requests made to the server and makes the page load faster.

<?php
class InlineImages {
	/** IE cannot display inline data larger than 32KiB
		also processing large images would take too much time */
	const SIZE_LIMIT = 32768;

	/** Regular expression to find URL definitions in CSS file */
	const REGEXP = '/(background(-image)?|list-style(-image)?|cursor):\ ?url\(([\'\"]?([^\'\)]+)[\'\"]?)\)/im';
	const REGIND = 5; //index of matching parenthesis where URL can be found

	/** Quotation character for CSS url() function
		- either ' or " (just in case you want to change it ;) */
	const QUOTE = '\''; //

	private $path;

	/**
	 * Creates new instance of CSS image replacer
	 *
	 * @param  [String] path where to look for images - URLs in CSS must be relative to this path!
	 */
	public function __construct($path) {
		$this->path = $path;
	}

	/**
	 * Replace images in CSS file with inline data
	 *
	 * @param  [String] CSS file content
	 * @return [String] replaced CSS
	 */
	public function process($data) {
		if (false !== preg_match_all(self::REGEXP, $data, $matches)) {
			$images = array();
			foreach ($matches[self::REGIND] as $index => $url) {
				$key = $matches[self::REGIND - 1][$index]; //URL including quotes (that must be removed from file as well)
				$filename = realpath($this->path . $url);
				if (false !== $filename && self::SIZE_LIMIT > filesize($filename)) {
					//get Base64-encoded content of the file
					$file = file_get_contents($filename);
					$base64 = base64_encode($file);
					//get Type of the file
					if (class_exists('finfo')) { //optional, requires PHP extension FileInfo (preferred)
						$finfo = new finfo(FILEINFO_MIME);
						$mime = $finfo->file($filename);
						$mime = explode(';', $mime)[0]; //returns also charset
					}
					elseif (function_exists('mime_content_type')) { //optional, requires PHP extension MimeType (deprecated)
						$mime = mime_content_type($filename);
					} else { //old way of detecting MIME from file extension
						preg_match('/\.([^\.]+)$/', $filename, $mime);
						$mime = 'image/' . $mime[1];
					}
					//save the content
					if (self::SIZE_LIMIT > count($base64)) { //base64 increses file size by ~20% - check the limit again
						$images[$key] = self::QUOTE . 'data:' . $mime . ';base64,' . $base64 . self::QUOTE;
					}
				}
			}
			if (count($images)) {
				$data = strtr($data, $images);
			}
		}

		return $data;
	}
}