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?

@ghost

This comment has been minimized.

Copy link

commented May 24, 2019

Thanks <3

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.