Compress –Zip– Multiple Files And Download with PHP January 10, 2012
Posted by Tournas Dimitrios in PHP.trackback
With PHP’s build-in ZipArchive Class we can archive multiple files into one bundle , compressed as Zip file-format . If you have read my previous article ” How To Make Files Downloadable with PHP ” then you already know that PHP can “send-out” raw HTTP headers to instruct the browser to behave accordingly ( redirection , authentication , catching , downloading ) . The magical function to do so is the header() function . This function allows us to define raw HTTP headers as a string (most of these header parameters are pretty self explanatory) . The script will then execute those headers and force the browser to render the page accordingly .
We have to bundle multiple files into one ZipArchive and instruct the browser the file-type it will receive . Compressing is accomplished in four steps :
- Instantiating a new ZipArchive Class (Creating a new object)
- Opening and assigning a name to the object .
- Adding files into the object (most likely with a loop )
- Closing the object
The final step is to “read ” the compressed object readfile(“Compressed-File-Name”) , which will be delivered to the browser . Of course some extra steps has to be implemented like — sanitizing all data received by the browser , redirecting empty requests (no $_POST data , for example if the user links directly to the script ) —- . I haven’t included an important step , download count limit . This step is left as home work to the reader 🙂 .
The code is divided into two files : the user-interface (index.php) where the user selects which files he would like to download . The second file “download.php” , receives the request and returns a compressed file .
Source code for Index.php :
<h2 style="color:blue;text-align:center"> Select which files you want to include in the zip-file <form action="download.php"" method="post"></pre> <p style="height: <span class=;">100px; overflow: auto; border: 5px solid #eee; background: #eee; color: #000; margin-bottom: 1.5em;width:250px"></p> <pre> <label><input type="checkbox" name="items[]" value="pic7.jpg" checked="checked"/> Thumb-image </label> <label><input type="checkbox" name="items[]" value="test.pdf"/> A test PDF file</label> <label><input type="checkbox" name="items[]" value="test.txt"/> A simple text file</label> <label><input type="checkbox" name="items[]" value="test.swf"/>A Flash animation</label> <label><br /> <input type="checkbox" name="items[]" value="pic1.png"/> Small icon for webdesign <label><input type="checkbox" name="items[]" value="pic2.png" /> Small icon for webdesign </label> <label><input type="checkbox" name="items[]" value="pic3.png" checked="checked" /> Small icon for webdesign </label> <label><input type="checkbox" name="items[]" value="pic4.png"/>Small icon for webdesign </label> <label><input type="checkbox" name="items[]" value="pic5.png"/> Small icon for webdesign</label> <label><input type="checkbox" name="items[]" value="pic6.png"/> Small icon for webdesign</label> </label><br /> </p> <input type="submit" name="formSubmit" value="Download" > </form>
Source code for download.php
<?php function zipFilesAndDownload($file_names,$archive_file_name,$file_path){ $zip = new ZipArchive(); //create the file and throw the error if unsuccessful if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE )!==TRUE) { exit("cannot open <$archive_file_name>\n"); } //add each files of $file_name array to archive foreach($file_names as $files) { $zip->addFile($file_path.$files,$files); } $zip->close(); $zipped_size = filesize($archive_file_name); header("Content-Description: File Transfer"); header("Content-type: application/zip"); header("Content-Type: application/force-download");// some browsers need this header("Content-Disposition: attachment; filename=$archive_file_name"); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header("Content-Length:". " $zipped_size"); ob_clean(); flush(); readfile("$archive_file_name"); unlink("$archive_file_name"); // Now delete the temp file (some servers need this option) exit; } if(isset($_POST['formSubmit'])) { //$file_names=$_POST['items'];// Always sanitize your submitted data!!!!!! //$file_names = filter_var_array($_POST['items']);//works but it's the wrong method $filter = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS) ; $file_names = $filter['items'] ; //Archive name $archive_file_name='DEMO-archive.zip'; //Download Files path $file_path= getcwd(). '/content/'; //cal the function zipFilesAndDownload($file_names,$archive_file_name,$file_path); } else { header("Refresh: 5; url= ./index.php "); print '<h1 style="text-align:center">You you shouldn\'t be here ......</pre> <p style="color: red;"><strong>redirection in 5 seconds</strong></p> <pre>'; exit; }
Thanks ! works for me
Great Code very usefull to me
@paulpandibpaul
I’m glad it was helpfull
thanks
good luck 🙂