Compress the files while downloading by client - php

I try to develop something like dropbox(very basic one). For one file to download, it's really easy. what i want is: when client asks me big file, i zip file in server side then send to user. But if file is too big it takes too many times to zip them and send to user.
is there any way to send files while they are compressing?
thanks for your help. Here is my simple sample code
<?php
function createzip($files, $zip_file) {
$zip = new ZipArchive;
if($zip->open($zip_file, ZipArchive::CREATE) === TRUE) {
foreach($files as $file){
$zip->addFile($file);
}
$zip->close();
return true;
}
else return false;
}
$ss=array("jj.mp4");
createzip($ss,'archiv.zip');
if(filesize("archiv.zip")>3000){
$vv=array("archiv.zip");
createzip($vv,"bbb.zip");
}
?>
use do while loop in if statement. Until file size become a desired value. I don't understand how to use do while loop and does it make it that type of compresses. Please help me out.

I use a method like this but I get file names from database if you wanna check and adapt to your codes..
$FList = $dl->select('dosyaYolu0, dosyaYolu1, dosyaYolu2, dosyaYolu3, dosyaYolu4')->table('tb_gelenEvrak')->where('mesajKodu', $filesnorm)->get();
$files = array(''.$FList->dosyaYolu0.'', ''.$FList->dosyaYolu1.'', ''.$FList->dosyaYolu2.'',''.$FList->dosyaYolu3.'', ''.$FList->dosyaYolu4.'');
$zipname = $filesnorm.'.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);

Related

PHP Download Multiple Files in Zip folder [duplicate]

How can I download multiple files as a zip-file using php?
You can use the ZipArchive class to create a ZIP file and stream it to the client. Something like:
$files = array('readme.txt', 'test.html', 'image.gif');
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file);
}
$zip->close();
and to stream it:
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
The second line forces the browser to present a download box to the user and prompts the name filename.zip. The third line is optional but certain (mainly older) browsers have issues in certain cases without the content size being specified.
This is a working example of making ZIPs in PHP:
$zip = new ZipArchive();
$zip_name = time().".zip"; // Zip name
$zip->open($zip_name, ZipArchive::CREATE);
foreach ($files as $file) {
echo $path = "uploadpdf/".$file;
if(file_exists($path)){
$zip->addFromString(basename($path), file_get_contents($path));
}
else{
echo"file does not exist";
}
}
$zip->close();
Create a zip file, then download the file, by setting the header, read the zip contents and output the file.
http://www.php.net/manual/en/function.ziparchive-addfile.php
http://php.net/manual/en/function.header.php
You are ready to do with php zip lib,
and can use zend zip lib too,
<?PHP
// create object
$zip = new ZipArchive();
// open archive
if ($zip->open('app-0.09.zip') !== TRUE) {
die ("Could not open archive");
}
// get number of files in archive
$numFiles = $zip->numFiles;
// iterate over file list
// print details of each file
for ($x=0; $x<$numFiles; $x++) {
$file = $zip->statIndex($x);
printf("%s (%d bytes)", $file['name'], $file['size']);
print "
";
}
// close archive
$zip->close();
?>
http://devzone.zend.com/985/dynamically-creating-compressed-zip-archives-with-php/
and there is also php pear lib for this
http://www.php.net/manual/en/class.ziparchive.php

Debugging zip archive and download

I'd like a bit of help debugging this code. I'm trying to zip some files, which I provide as paths to Ziparchive. I think the zip file is empty, possibly. When I test this on a staging site I get a 'decompression failed' error. When I test this locally I get the following error in php logs
PHP Warning: readfile(images.zip): failed to open stream: No such file or directory in /Applications/MAMP/htdocs/8018_Whites/wordpress/downloadzip.php on line 29.
Here is the code:
<?php
//get image urls string
//$cat_string = "url1,url2,url3..."
if (isset($_GET['category-images'])) {
$cat_string=$_GET['category-images'];
}
//change string to array
$cat_array=explode(",", $cat_string);
$files=$cat_array;
$zipname = 'images.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
if(!strstr($file,'.php')) $zip->addFile($file);
}
$zip->close();
if ($zipname) {
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
exit();
}
?>
Do I need to add ob_start/ob_flush to this code, and should I put the ob_flush after readfile?
All files and Zip folder to give absolute path. so zip is properly created.
<?php
$zip_root ='/var/www/gplhome/'
$file_root ='/var/www/gplhome/project/'
//get image urls string
//$cat_string = "url1,url2,url3..."
if (isset($_GET['category-images'])) {
$cat_string=$_GET['category-images'];
}
//change string to array
$cat_array=explode(",", $cat_string);
$files=$cat_array;
$zipname = $zip_root.'images.zip';
$zip = new ZipArchive;
if ($zip->open($zipname, ZIPARCHIVE::CREATE) != TRUE) {
die("Could not open archive");
}
foreach ($files as $file) {
if(!strstr($file_root.$file,'.php')) $zip->addFile($file_root.$file);
}
$zip->close();
if ($zipname) {
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
exit();
}
?>
check the return value of $zip->close(), it returns false on error.
check the return value of $zip->addFile(), it returns false on error.
ensure that you use only file name for headers and full name for readfile.
check if the file is created. Replace
if ($zipname) {
with
if (is_readable($zipname)) {
don't put ?> and the end of the php file

PHP zip function

I'm trying to build a directory tree with specific files from an array and push it to download. This part is working fine.
The problem is when I try to fill the specific files with content.
After the download is finished the files are empty.
However the switch case statement is executed and all the methods are working.
The problem I think is around my zip function, but I don't really know what should I search for (or maybe the code design is not the best one).
<?php
include_once 'class.file.php';
class CreateComponent{
function __construct(){
if (isset($_POST['name'])){
$this->createDirectoryTree($_POST['name']);
}
else{
echo '<h1>error!</h1>';
}
}
function createDirectoryTree($component_name){
$component_name="com_".$component_name;
$this->create_zip($component_name);
}
function create_zip($component) {
$jcomp=str_replace("com_", "", $component);
$dirs= array(
$jcomp.'.xml',
'site/'.$jcomp.'.php',
'site/views/index.html',
'site/views/to_change/index.html',
'site/views/to_change/tmpl/index.html',
'site/views/to_change/tmpl/default.xml',
'site/views/to_change/tmpl/default.php',
'site/models/index.html',
'site/controllers/index.html',
'site/tables/index.html',
'site/index.html',
'admin/index.html',
'admin/views/index.html',
'admin/models/index.html',
'admin/controllers/index.html',
'admin/sql/updates/index.html',
'admin/sql/updates/mysql/0_1.sql'
);
$file = tempnam("tmp", "zip");
$zip = new ZipArchive();
foreach ($dirs as $dir){
$zip->open($file, ZIPARCHIVE::CREATE);
$zip->addEmptyDir($dir);
switch ($dir){
case (substr( $dir, strrpos( $dir, '/' )+1 ) == "index.html"):
$zip->addFromString($dir, '<html><body bgcolor="#FFFFFF"></body></html>');
break;
case "site/$jcomp.php":
$main_php= new File();
// echo $main_php->main_controller($jcomp);
$zip->addFromString($dir,$main_php->main_controller($jcomp));
$zip->addFromString($dir, '');
break;
case "$jcomp.xml":
$main_php= new File();
$zip->addFromString($dir,$main_php->main_xml($jcomp));
break;
}
$zip->addFromString($dir, '');
}
$zip->close();
// Stream the file to the client
header('Content-Type: application/zip');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename= "'.$component.'.zip"');
readfile($file);
unlink($file);
}
}
$component= new CreateComponent();
At a first glance I would change the following lines
$zip = new ZipArchive();
foreach ($dirs as $dir){
$zip->open($file, ZIPARCHIVE::CREATE);
$zip->addEmptyDir($dir);
to
$zip = new ZipArchive();
$zip->open($file, ZIPARCHIVE::CREATE);
foreach ($dirs as $dir){
$zip->addEmptyDir($dir);
as you are opening the file everytime you add a directory and it seems wrong to me.
On the other hand I would set a component name policy and check for it in the constructor in order to prevent input exploitation.
I don't know, maybe a good name policy would be - just alpha chars, numbers and dashes are allowed into a module name -

Zip multiple database PDF blob files

I have a database table that contains numerous PDF blob files. I am attempting to combine all of the files into a single ZIP file that I can download and then print.
Please help!
<?php
include '../config.php';
include '../connect.php';
$session = $_GET['session'];
$query = "SELECT $tbl_uploads.username, $tbl_uploads.description,
$tbl_uploads.type, $tbl_uploads.size, $tbl_uploads.content,
$tbl_members.session
FROM $tbl_uploads
LEFT JOIN $tbl_members
ON $tbl_uploads.username = $tbl_members.username
WHERE $tbl_members.session = '$session'";
$result = mysql_query($query) or die('Error, query failed');
$files = array();
while(list($username, $description, $type, $size, $content) =
mysql_fetch_array($result)) {
$files[] = "$username-$description.pdf";
}
$zip = new ZipArchive;
$zip->open('file.zip', ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=filename.zip');
header('Content-Length: ' . filesize($zipfilename));
readfile($zipname);
exit();
?>
Your PDF data is stored in the database in BLOB fields, I don't see you putting this data in a file. So your ZIP will not contain any files because you don't add real existing files to it.
This is what you are currently doing:
Reading your data from the database
Creating an array of filenames
Creating a ZIP of filenames that might not exist
This what you should do:
Reading your data from the database
Creating an array of filenames
Write your BLOB data into that files
Creating a ZIP of files that exist
Example:
$files = array();
while(list($username, $description, $type, $size, $content) =
mysql_fetch_array($result)) {
$files[] = "$username-$description.pdf";
// write the BLOB Content to the file
if ( file_put_contents("$username-$description.pdf", $content) === FALSE ) {
echo "Could not write PDF File";
}
}
What you should do if that works for you:
Write the files in a temporary folder (maybe with some help of http://php.net/tempnam) somewhere else and maybe remove them after your archiving process.
There is also a second problem in your code, you use $zipfilename for calculating the content-length and $zipname to read the file and no variable to create the zip. Since $zipfilename and $zipname is not defined, this won't work.
You should define $zipfilename with a ZIP filename and also use that same variable when creating the zip file.
Example:
// a temp filename containing the current unix timestamp
$zipfilename = 'temp_' . time() . '.zip';
$zip->open($zipfilename, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=filename.zip');
header('Content-Length: ' . filesize($zipfilename));
readfile($zipfilename);
pdftk will merge multiple PDF files, as well as PDFsam..

Download multiple files as a zip-file using php

How can I download multiple files as a zip-file using php?
You can use the ZipArchive class to create a ZIP file and stream it to the client. Something like:
$files = array('readme.txt', 'test.html', 'image.gif');
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file);
}
$zip->close();
and to stream it:
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
The second line forces the browser to present a download box to the user and prompts the name filename.zip. The third line is optional but certain (mainly older) browsers have issues in certain cases without the content size being specified.
This is a working example of making ZIPs in PHP:
$zip = new ZipArchive();
$zip_name = time().".zip"; // Zip name
$zip->open($zip_name, ZipArchive::CREATE);
foreach ($files as $file) {
echo $path = "uploadpdf/".$file;
if(file_exists($path)){
$zip->addFromString(basename($path), file_get_contents($path));
}
else{
echo"file does not exist";
}
}
$zip->close();
Create a zip file, then download the file, by setting the header, read the zip contents and output the file.
http://www.php.net/manual/en/function.ziparchive-addfile.php
http://php.net/manual/en/function.header.php
You are ready to do with php zip lib,
and can use zend zip lib too,
<?PHP
// create object
$zip = new ZipArchive();
// open archive
if ($zip->open('app-0.09.zip') !== TRUE) {
die ("Could not open archive");
}
// get number of files in archive
$numFiles = $zip->numFiles;
// iterate over file list
// print details of each file
for ($x=0; $x<$numFiles; $x++) {
$file = $zip->statIndex($x);
printf("%s (%d bytes)", $file['name'], $file['size']);
print "
";
}
// close archive
$zip->close();
?>
http://devzone.zend.com/985/dynamically-creating-compressed-zip-archives-with-php/
and there is also php pear lib for this
http://www.php.net/manual/en/class.ziparchive.php

Categories