A small PHP CLI script to compress (or minify) a CSS style sheet. It does require that you include the CommandLine parser class.
#!/usr/bin/php -q
<?php
/**
* Compress CSS
*
* A small PHP CLI script to compress (or minify) a CSS style sheet.
* It does require that you include the CommandLine parser class
* (http://jonlabelle.com/snippets/view/php/php-cli-parser).
*
* @author Jon LaBelle, http://jonlabelle.com
* Date: Sun Sep 09 2012 16:25:10 GMT-05:00 (CDT)
*/
include 'CommandLine.php';
function show_help($display = true) {
$script = basename($_SERVER['argv'][0]);
$help = <<<ENDHELP
Usage: {$script} [OPTIONS]
Compress a CSS style-sheet. Removes comments and extra spaces in code.
-s, --source=FILE The source CSS file that will be compressed.
-w, --overwrite Overwrite the source CSS file with the compressed output.
-o, --output=FILE Specify the output of the compressed CSS file.
-h, --help Display help and exit.
ENDHELP;
if ($display) {
echo $help . "\n";
} else {
return $help . "\n";
}
}
/**
* Remove spaces around curly brackets, colons, semi-colons, parenthesis and
* commas.
*
* @param string $input The CSS to process.
* @return string
*/
function remove_extra_spaces($input) {
return preg_replace('!\s*(:|;|,|}|{|\(|\))\s*!', '$1', $input);
}
/**
* Remove CSS comments
*
* @param string $input The CSS to process.
* @return string
*/
function remove_css_comments($input) {
return preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $input);
}
/**
* Delete directory recursively
*
* This PHP function scans a given directory and deletes all files and
* subdirectories it finds and has permission to delete.
*
* Per default it removes the given directory totally, but you can
* specify to just "empty" it instead. In this case it deletes
* everything inside the given directory and keeps the directory itself.
*
* @author http://lixlpixel.org/recursive_function/php/recursive_directory_delete/
* @param $directory string The path to directory.
* @param $empty bool Set to true to leave the directory in tact, but empty all it's contents.
* @return boolean
*/
function remove_dir($directory, $empty = false) {
if (substr($directory, -1) == '/') { // remove appending slashes
$directory = substr($directory, 0, -1);
}
if (!file_exists($directory) || !is_dir($directory)) {
return false;
} elseif (!is_readable($directory)) {
return false;
} else {
$handle = opendir($directory);
while (false !== ($item = readdir($handle))) {
if ($item != '.' && $item != '..') {
$path = $directory . '/' . $item;
if (is_dir($path)) {
remove_dir($path);
} else {
unlink($path);
}
}
}
closedir($handle);
// if the option to empty is not set to true
if ($empty === false) {
if (!rmdir($directory)) {
return false;
}
}
return true;
}
}
/**
* Delete a file.
*
* @param string $file The complete path to file.
*/
function delete_file($file) {
if (file_exists($file)) {
unlink($file);
}
}
/**
* Reads the content of the file into a string.
*
* @param string $file The complete file path.
* @return string
*/
function read_file_contents($file) {
$contents = '';
if (file_exists($file)) {
$fh = fopen($file, "r");
$contents = fread($fh, filesize($file));
fclose($fh);
}
return $contents;
}
/**
* Write contents to a file.
* NOTE: Will overwrite file if exists.
*
* @param string $file The complete file path.
* @param string $content The content to write.
* @return void
*/
function write_file_contents($file, $content) {
$fh = fopen($file, 'w') or die("\nCannot open $file for writing.");
fwrite($fh, $content);
fclose($fh);
}
/**
* Gets the file extensions.
*
* @param string $file
* @return string The file extension.
*/
function get_file_extension($file) {
return strtolower(substr(strrchr($file, "."), 1));
}
// ---------------------------------------------------------------
// MAIN
// ---------------------------------------------------------------
// no arguments provided
if ($_SERVER['argc'] == 1) {
fwrite(STDERR, show_help(false));
exit(1);
} else {
// Retrieve command-line arguments
$allowed = array(
's', 'source',
'w', 'overwrite',
'o', 'output',
'h', 'help'
);
try {
$options = CommandLine::parseOptions($_SERVER['argv'], $allowed);
} catch (CommandLineOptionException $e) {
fwrite(STDERR, $e->getMessage() . "\n" . show_help(false));
exit(1);
}
}
// show help if requested
if (isset($options['h']) || isset($options['help'])) {
show_help();
exit();
}
if (!isset($options['s']) && !isset($options['source'])) {
fwrite(STDERR, 'ERROR: Source file option is not set. Use -s ' . 'or --source.' . "\n");
exit(1);
}
$source_file = (isset($options['s'])) ? $options['s'] : $options['source'];
$output_file = false;
$overwrite_source = false;
if (isset($options['w']) && !isset($options['o']) || !isset($options['output'])) {
$overwrite_source = true;
} elseif (isset($options['overwrite'])) {
$overwrite_source = true;
} else {
if (!isset($options['o']) && !isset($options['output'])) {
fwrite(STDERR, 'ERROR: Output file not set, and you did not set the overwrite option (-w)' . "\n");
exit(1);
} else {
$output_file = (isset($options['o'])) ? $options['o'] : $options['output'];
}
}
if (!file_exists($source_file) || filesize($source_file) <= 0) {
fwrite(STDERR, 'ERROR: Source (' . $source_file. ') file does not exist. Option -s ' . 'or --source.' . "\n");
exit(1);
}
// finally, the meat and potatoes...
$source_file_contents = remove_css_comments(read_file_contents($source_file));
$source_file_contents = remove_extra_spaces($source_file_contents);
if ($overwrite_source === true) { // overwrite source file with the removed comments content?
delete_file($source_file);
write_file_contents($source_file, $source_file_contents);
} else {
write_file_contents($output_file, $source_file_contents);
}
?>