Hi!
Minimize HTTP requests. One of the suggestion I always read is to combine files, so I made a little Class that merges files on the fly, the supported formats are CSS and Javascript. With little efforts, I think, it can work fine also with JSON and CSV.
Usage is simple:
- create a file that will serve data and in which the class is included
- set config variables: method, path and type
- use a link in this format:
/merge/?css&first.css&second.css&third.css
Basically:
<?php
$list = $_SERVER['QUERY_STRING'];
$config['path']['css'] = '/css/';
$config['path']['js'] = '/js/';
include 'merger.class.php';
try
{
$z = new Merger($list,$config);
$exp = 60*60*24;
header("Cache-Control: private");
header("Cache-Control: maxage=".$exp);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$exp) . ' GMT');
header('Accept-Ranges: bytes');
header('Content-Type:' . $z->output_mime());
header('Content-Length: '. $z->output_sizes());
echo $z->output_data();
}
catch(Exception $e)
{
echo $e->getMessage();
exit();
}
?>
And in the file:
<link rel="stylesheet" href="/merge/?css&a.css&b.css&d.css" type="text/css" media="all" charset="utf-8" />
<script type="text/javascript" src="/merge/?js&jquery-1.7.2.min.js&include.js"></script>
Method and Path are setted in the script and passed as array in the second argument:
$config['method'] = 'get';
$config['path']['css'] = '/css/';
$z = new Merger($list, $config);
get is the default value for method, so it can be omitted, the alternative is cli. Type is setted in the link as first argument:
/merge/?css
this will select the path and the mimes to match, after the first argument append all the files that you want to merge:
/merge/?css&alfa.css&beta.css&gamma.css&...
/merge/?js&javascript_framework.js&calc.js&form.js&...
the string can be served as encoded through urlencode/rawurlencode or not. The class will check for duplicates names, and will remove them so you won't merge same data. At the moment there no check about contents, but this is simple to achieve, it's enough to use md5_file()
.
As I wrote, methods are: cli and get. The script can ran from CLI, for example to merge files and save them, just add file_put_contents()
in the try{}
block and change $list
as below:
$list = $argv;
# ...
file_put_contents(md5($z->output()).'.'.$z->type,$z->output_data(),LOCK_EX);
Instead of $argv
for CLI input or $_SERVER['QUERY_STRING']
for GET, you can pass a simple array:
$list = array('css','alfa.css','beta.css','gamma.css');
but in this case you need a second serving script for js or a switch statement. I'm attaching also a complete example, with css and js files, just place them in the root.
H OOPs
Hope it is useful and easy to understand. This is also my first snippet here, hope I didn't breach rules :D
Requirements
PHP >= 4.3.0, PHP 5
Few Notes
Finfo and linux command file output text/plain on ubuntu and, in some cases, these files can also be detected as text/x-c or text/x-c++. In order to work, just leave the correct mime type at the end of each array.
Array_filter() is used to prevent errors, given a&b&
, the last "&" will generate a key with an empty value:
$s = 'a&b&';
print_r(explode('&',$s));
# outputs
Array
(
[0] => a
[1] => b
[2] =>
)