Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP Function to Minify HTML, CSS and JavaScript
<?php
/**
* -----------------------------------------------------------------------------------------
* Based on `https://github.com/mecha-cms/mecha-cms/blob/master/system/kernel/converter.php`
* -----------------------------------------------------------------------------------------
*/
// HTML Minifier
function minify_html($input) {
if(trim($input) === "") return $input;
// Remove extra white-space(s) between HTML attribute(s)
$input = preg_replace_callback('#<([^\/\s<>!]+)(?:\s+([^<>]*?)\s*|\s*)(\/?)>#s', function($matches) {
return '<' . $matches[1] . preg_replace('#([^\s=]+)(\=([\'"]?)(.*?)\3)?(\s+|$)#s', ' $1$2', $matches[2]) . $matches[3] . '>';
}, str_replace("\r", "", $input));
// Minify inline CSS declaration(s)
if(strpos($input, ' style=') !== false) {
$input = preg_replace_callback('#<([^<]+?)\s+style=([\'"])(.*?)\2(?=[\/\s>])#s', function($matches) {
return '<' . $matches[1] . ' style=' . $matches[2] . minify_css($matches[3]) . $matches[2];
}, $input);
}
if(strpos($input, '</style>') !== false) {
$input = preg_replace_callback('#<style(.*?)>(.*?)</style>#is', function($matches) {
return '<style' . $matches[1] .'>'. minify_css($matches[2]) . '</style>';
}, $input);
}
if(strpos($input, '</script>') !== false) {
$input = preg_replace_callback('#<script(.*?)>(.*?)</script>#is', function($matches) {
return '<script' . $matches[1] .'>'. minify_js($matches[2]) . '</script>';
}, $input);
}
return preg_replace(
array(
// t = text
// o = tag open
// c = tag close
// Keep important white-space(s) after self-closing HTML tag(s)
'#<(img|input)(>| .*?>)#s',
// Remove a line break and two or more white-space(s) between tag(s)
'#(<!--.*?-->)|(>)(?:\n*|\s{2,})(<)|^\s*|\s*$#s',
'#(<!--.*?-->)|(?<!\>)\s+(<\/.*?>)|(<[^\/]*?>)\s+(?!\<)#s', // t+c || o+t
'#(<!--.*?-->)|(<[^\/]*?>)\s+(<[^\/]*?>)|(<\/.*?>)\s+(<\/.*?>)#s', // o+o || c+c
'#(<!--.*?-->)|(<\/.*?>)\s+(\s)(?!\<)|(?<!\>)\s+(\s)(<[^\/]*?\/?>)|(<[^\/]*?\/?>)\s+(\s)(?!\<)#s', // c+t || t+o || o+t -- separated by long white-space(s)
'#(<!--.*?-->)|(<[^\/]*?>)\s+(<\/.*?>)#s', // empty tag
'#<(img|input)(>| .*?>)<\/\1>#s', // reset previous fix
'#(&nbsp;)&nbsp;(?![<\s])#', // clean up ...
'#(?<=\>)(&nbsp;)(?=\<)#', // --ibid
// Remove HTML comment(s) except IE comment(s)
'#\s*<!--(?!\[if\s).*?-->\s*|(?<!\>)\n+(?=\<[^!])#s'
),
array(
'<$1$2</$1>',
'$1$2$3',
'$1$2$3',
'$1$2$3$4$5',
'$1$2$3$4$5$6$7',
'$1$2$3',
'<$1$2',
'$1 ',
'$1',
""
),
$input);
}
// CSS Minifier => http://ideone.com/Q5USEF + improvement(s)
function minify_css($input) {
if(trim($input) === "") return $input;
return preg_replace(
array(
// Remove comment(s)
'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')|\/\*(?!\!)(?>.*?\*\/)|^\s*|\s*$#s',
// Remove unused white-space(s)
'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/))|\s*+;\s*+(})\s*+|\s*+([*$~^|]?+=|[{};,>~+]|\s*+-(?![0-9\.])|!important\b)\s*+|([[(:])\s++|\s++([])])|\s++(:)\s*+(?!(?>[^{}"\']++|"(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')*+{)|^\s++|\s++\z|(\s)\s+#si',
// Replace `0(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)` with `0`
'#(?<=[\s:])(0)(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)#si',
// Replace `:0 0 0 0` with `:0`
'#:(0\s+0|0\s+0\s+0\s+0)(?=[;\}]|\!important)#i',
// Replace `background-position:0` with `background-position:0 0`
'#(background-position):0(?=[;\}])#si',
// Replace `0.6` with `.6`, but only when preceded by `:`, `,`, `-` or a white-space
'#(?<=[\s:,\-])0+\.(\d+)#s',
// Minify string value
'#(\/\*(?>.*?\*\/))|(?<!content\:)([\'"])([a-z_][a-z0-9\-_]*?)\2(?=[\s\{\}\];,])#si',
'#(\/\*(?>.*?\*\/))|(\burl\()([\'"])([^\s]+?)\3(\))#si',
// Minify HEX color code
'#(?<=[\s:,\-]\#)([a-f0-6]+)\1([a-f0-6]+)\2([a-f0-6]+)\3#i',
// Replace `(border|outline):none` with `(border|outline):0`
'#(?<=[\{;])(border|outline):none(?=[;\}\!])#',
// Remove empty selector(s)
'#(\/\*(?>.*?\*\/))|(^|[\{\}])(?:[^\s\{\}]+)\{\}#s'
),
array(
'$1',
'$1$2$3$4$5$6$7',
'$1',
':0',
'$1:0 0',
'.$1',
'$1$3',
'$1$2$4$5',
'$1$2$3',
'$1:0',
'$1$2'
),
$input);
}
// JavaScript Minifier
function minify_js($input) {
if(trim($input) === "") return $input;
return preg_replace(
array(
// Remove comment(s)
'#\s*("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')\s*|\s*\/\*(?!\!|@cc_on)(?>[\s\S]*?\*\/)\s*|\s*(?<![\:\=])\/\/.*(?=[\n\r]|$)|^\s*|\s*$#',
// Remove white-space(s) outside the string and regex
'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/)|\/(?!\/)[^\n\r]*?\/(?=[\s.,;]|[gimuy]|$))|\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#s',
// Remove the last semicolon
'#;+\}#',
// Minify object attribute(s) except JSON attribute(s). From `{'foo':'bar'}` to `{foo:'bar'}`
'#([\{,])([\'])(\d+|[a-z_][a-z0-9_]*)\2(?=\:)#i',
// --ibid. From `foo['bar']` to `foo.bar`
'#([a-z0-9_\)\]])\[([\'"])([a-z_][a-z0-9_]*)\2\]#i'
),
array(
'$1',
'$1$2',
'}',
'$1$3',
'$1.$3'
),
$input);
}
@alan-zhang-

This comment has been minimized.

Copy link

commented Jun 27, 2017

It's a great fork that saved me for original one caused a weird bug for code:

{% for lang_abbr, lang_name in langs %}
    <li>
        <a class="flag flag-{{ lang_abbr }}" title="{{ lang_name }}" href="{{ sites[lang_abbr] ~ uri }}">
            {{ lang_name }}
        </a>
    </li>
{% endfor %}
@saosangmo

This comment has been minimized.

Copy link

commented Aug 27, 2017

this code will return wrong result
<script type="text/javascript"><!--$('.vtabs a').tabs();</script>

@thunder87

This comment has been minimized.

Copy link

commented Dec 15, 2017

@saosangmo

Ofc it will, it's not valid code. You have a HTML comment tag that shouldn't be there :)

@Simbiat

This comment has been minimized.

Copy link

commented Mar 3, 2018

CSS function strips spaces that are required in "calc" functions

@Simbiat

This comment has been minimized.

Copy link

commented Mar 3, 2018

Javascript function turns
string = string.replace(/\//g, '_').replace(/\+/g, '-');
into
string = string.replace(/\

@kiptoyot

This comment has been minimized.

Copy link

commented Apr 25, 2018

How to solve this error in suiteCRM.when i try to create a target list it shows this error
Fatal error: Uncaught Error: Call to undefined function minify_css() in C:\xampp\htdocs\SuiteCRM\include\Smarty\plugins\block.minify.php:15 Stack trace: #0 [internal function]: {closure}(Array) #1 C:\xampp\htdocs\SuiteCRM\include\Smarty\plugins\block.minify.php(16): preg_replace_callback('#<([^<]+?)\s+st...', Object(Closure), '<label for="dom...') #2 C:\xampp\htdocs\SuiteCRM\cache\smarty\templates_c%%B9^B9B^B9B2C976%%EditView.tpl.php(654): smarty_block_minify(Array, '<label for="dom...', Object(Sugar_Smarty), false) #3 C:\xampp\htdocs\SuiteCRM\include\Smarty\Smarty.class.php(1264): include('C:\xampp\htdocs...') #4 C:\xampp\htdocs\SuiteCRM\include\Sugar_Smarty.php(151): Smarty->fetch('cache/themes/Su...', NULL, NULL, false) #5 C:\xampp\htdocs\SuiteCRM\include\TemplateHandler\TemplateHandler.php(365): Sugar_Smarty->fetch('cache/themes/Su...') #6 C:\xampp\htdocs\SuiteCRM\include\EditView\EditView2.php(909): TemplateHandler->displayTemplate('ProspectLists', 'EditView', 'include/EditVie...', false, Array) #7 C:\xampp\htdoc in C:\xampp\htdocs\SuiteCRM\include\Smarty\plugins\block.minify.php on line 15

@kiptoyot

This comment has been minimized.

Copy link

commented Apr 25, 2018

Guys i need your assistance please

@MattIPv4

This comment has been minimized.

Copy link

commented Aug 18, 2018

Hey guys, this removes spaces in css that are inside a calc() which leads to it becoming an invalid property value, does anyone know the fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.