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'm using this code for database backup with zipped type and download automaticly.
you can get referance this codes
<?php
$DBUSER="username";
$DBPASSWD="password";
$DATABASE="dbname";
$filename = "backup-" . date("d-m-Y") . ".sql.gz";
$mime = "application/x-gzip";
header( "Content-Type: " . $mime );
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
$cmd = "mysqldump -u $DBUSER --password=$DBPASSWD $DATABASE | gzip --best";
passthru( $cmd );
echo ('Backup Ok !');
exit(0);
?>

Related

Readfile() has started displaying on page

Part of what's being displayed:
PKd�wL��� ���/images/image_0.jpg��ex\K��1昙�3�133���;ffff����Ԇ�����w�̼߳�cw��딎�$��Z�������&QRTB�|>��E��M5���|�~b��)�o�3�� �>s���o�'���^B�O��V ����#���Q?S#(�� 6���v4���8����vvV�sy}#�_ �O��s�o���L�7Fv.F&�ol��WV.V��?�����g�W!�/w!�������K�oLL�1`���G�p�X���T�>C�#��L��)q���s��3�g�8�p�O�?
I'm trying to download images into zip file, this is what i've got so far:
if (count($headers->images) > 0) {
$counter = 0;
$zip = new ZipArchive();
$tmpFile = "tmpFolder/tmp" . strtotime("now") . ".zip";
$zip->open($tmpFile, ZipArchive::CREATE);
foreach($headers->images as $key => $images) $zip->addFromString("/images/image_" . $counter++ . ".jpg", file_get_contents($images));
$zip->close();
if (file_exists($tmpFile)) {
$fname = basename($_POST["titleZipFile"] . ".zip");
$size = filesize($tmpFile);
header("Content-Type: archive/zip");
header("Content-Disposition: attachment; filename=$fname");
header("Content-Length: " . $size);
ob_end_clean();
readfile($tmpFile);
//unlink($tmpFile);
echo "<div id='reportMessage'><p>You have successfully save images. Please go to your folder " . $_POST["titleZipFile"] . ".zip<p></div>";
}
}
if I remove the unlink($tmpFile); line then the tmp zip is actually generated and has the images inside the zip. However it's not actually showing the zip downloading in browser.
Does any one have any ideas why this could be happening?
Try to change the header for the content type to the following. I think the header is causing the browser problems with interpreting what it is supposed to do. Try the following type.
header('Content-type: application/zip');

Why zip file can't be opened after downloaded but fine via manual transfer?

I searched and tried a few previous questions/example codes, but couldn't get this to work.
I'm trying to deliver the results to end-users via PHP code. Here is my code.
$varZipFile = $varBaseNameParts[0] . '.' . $varDate . '.zip';
$varZipDir = $varBaseNameParts[0] . '_' . $varDate;
$zip = new ZipArchive();
$zip->open($varZipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$zip->addFile('008.csv');
$zip->addFile('002.csv');
$zip->close(); // mark line xxx
header("Content-Type: application/zip");
header("Content-disposition: attachment;filename=$varZipFile");
header('Content-Length: ' . filesize($varZipFile)); // with or without this line, got the same error
header("Content-Type: application/force-download"); // with or without this line, got the same error
readfile($varZipFile);
I got the .zip file in my browser. However WinZip cannot open it, neither can 7-Zip. WinZip complains that "Error: Central directory not found".
Interestingly, when I manually transfer the file via WinSCP from my server to my Windows machine, I can open the file with either WinZip or 7-Zip. This indicates it works all fine to 'mark line xxx', and problems occurs in the header lines.
TIA!
Your ouput buffer may not be cleared before you try to serve the download. Try to clean the output buffer before serving the download with the ob_clean() function like this:
$zip->close(); // mark line xxx
ob_clean();
Your code is working well on my side, debug this $varBaseNameParts[0] to see if the value is correct or try the below code.
// $name = name of the archive
// $archive_directory = directory to save the archive
// $file_array = list of files
function create_archive($name, $archive_directory, $file_array) {
$target_file = $archive_directory . '/' . $name . date('m-d-y').date('h-i-sa') . '.zip';
$zip = new ZipArchive();
if (count($file_array)) {
if ($zip->open($target_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
foreach ($file_array as $file) {
$zip->addFile($file);
}
$zip->close();
chmod($target_file, 0777);
return $target_file;
}
}
return null;
}
function create_download($archive) {
$file_name = basename($archive);
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=$file_name");
header("Content-Length: " . filesize($archive));
readfile($archive);
}
// create the archive file
$archive = create_archive('test', 'archive', ['008.csv', '002.csv']);
if ($archive) {
create_download($archive);
}

Compress the files while downloading by client

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);

PHP download prompt script downloads to server as well

I wrote a PHP script that creates a zipfile and prompts the browser for download. Not only does it download to the client, for some reason it also creates a duplicate zipfile in my server in the same directory as this script.
I only want this script to download to the client, and not a duplicate on my server.
$layoutName = $_POST['layoutName'];
$htmlContent = $_POST['htmlContent'];
$layoutDir = 'http://myapp.com/public/views/layouts/' . $layoutName;
$zipFileName = 'Myapp-' . $layoutName . '.zip';
$decompressedFolderName = 'Myapp-' . $layoutName;
$zip = new ZipArchive();
$zip->open($zipFileName, ZipArchive::CREATE);
if($zip)
{
// Add index.html
$zip->addFromString('index.html', $htmlContent);
// Add CSS Folder
$cssContent = file_get_contents($layoutDir . '/css/default.css', false);
$zip->addFromString('css/default.css', $cssContent);
} else {
echo 'Could not create zip';
}
$zip->close();
header('Content-Type: application/octet-type');
header('Content-Disposition: attachment; filename=Myapp-' . $layoutName . '.zip');
header('Content-Length: ' . filesize($zipFileName));
ob_clean();
flush();
echo file_get_contents($zipFileName);
exit;
UPDATE
PROBLEM SOLVED. This code now works!
That was my exact problem. I changed readfile() to file_get_contents(), and now it doesn't create the file on my server.

Zip file not downloading in PHP

I've implemented the code to Create Zip Folder of Files (from db path) and download zipped folder in PHP. I am using Ubuntu OS.
public function actionDownload($id) {
$model = $this->loadModel($id, 'Document');
$results = array();
$results = $this->createZip($model);
$zip = $results[0];
$size = filesize($zip->filename);
if ($zip->filename) {
header("Content-Description: File Transfer");
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=\"" . $model->name . "\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $size);
ob_end_flush();
flush();
readfile($zip->filename);
// To Store User Transaction Data
//$this->saveTransaction();
//ignore_user_abort(true);
unlink($zip->filename);
$zip->close();
// Delete newly created files
foreach ($results[1] as $fl) {
unlink($fl);
}
}
}
public function createZip($model) {
$data = Document::model()->findAll('parent_folder=:id', array(':id' => (int) $model->document_id));
$fileArr = array();
foreach ($data as $type) {
$fileArr[] = $type->path;
}
$filestozip = $fileArr; // FILES ARRAY TO ZIP
$path = Yii::app()->basePath . DS . 'uploads' . DS . Yii::app()->user->id;
//$model->path = trim(DS . $path . DS); // DIR NAME TO MOVE THE ZIPPED FILES
$zip = new ZipArchive();
$files = $filestozip;
$zipName = "USR_" . Yii::app()->user->id . "_" . $model->name . "_" . date("Y-m-d") . ".zip";
$fizip = $path . DS . $zipName;
if ($zip->open($fizip, ZipArchive::CREATE) === TRUE) {
foreach ($files as $fl) {
if (file_exists($fl)) {
$zip->addFile($fl, basename($fl)) or die("<p class='warning'>ERROR: Could not add file: " . $fl . "</p>");
}
}
}
$resultArr = array();
$resultArr[] = $zip;
$resultArr[] = $files;
return $resultArr;
}
The Zip creation code working fine and its creating zip file there but the issue is owner of the file is www-data and file permission is Read-Only.
When I am trying to set chmod($zip->filename, 0777) permission to that zipped folder then its showing an error?
Error 500
chmod(): No such file or directory
In fact file is present there.
If I am trying without chmod() then its showing me error of
Error 500
filesize(): stat failed for /home/demo.user/myapp/public_html/backend/uploads/1/USR_1_kj_2013-12-23.zip
and then its not downloading the zip file.
This is really weird issue I am facing. It seem to be some permission issue of zip file that's why filesize() is not able to perform any operation on that file but strange thing is chmod() also not working.
Need Help on this.
Thanks
If www-data has read permissions, the file permissions are properly set. No chmod required.
You need to call $zip->close() before the download, as only on $zip->close() the file will be written to disk. readfile() will not work unless the file is written to disk.
A smarter way, could be to create the archive in memory only using the php://memory stream wrapper. However this is only an option if you need the archive for a single download only.

Categories