In CakePHP controller I have the logic to generate a ZIP which is as follows and works perfectly fine, I can find the ZIP archive on the server:
function getAttachmentsInZip( $meetingId = null ){
$this->autoRender = false;
$this->request->allowMethod( ['post'] );
$allTasksWithFiles_query = $this->Tasks->find('all')
->where(['Tasks.uploaded_file_path != ' => 'NULL']);
$allTasksWithFiles = $allTasksWithFiles_query->toArray();
$files = array();
foreach( $allTasksWithFiles as $taskWithFile ){
$files[] = $taskWithFile['uploaded_file_path'];
}
if( !empty( $files ) ){
$destination = 'uploads/archives/meeting_' . $meetingId .'.zip';
$zip = new ZipArchive();
$zip->open( $destination, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE );
foreach( $files as $file ){
$zip->addFile('uploads/uploaded_files/' . $file, $file);
}
$zip->close();
}
}
However, I am completely unable to return the archive straight to user's browser. The closest I got was the following snippet, but the archive is broken and cannot be opened:
header("Content-type: application/zip");
header('Content-Disposition: attachment; filename="' . $destination . '"');
header("Pragma: no-cache");
header("Expires: 0");
readfile("asd");
Any help or guidance is much appreciated. If I should have/could have provided more code — please ask.
Related
I want to download my zip file by a variable ($direccion) that I want to assign to it and when I try to do it, it comes out that the file is corrupted.
$file_name = basename('C:/xampp/htdocs/issv/upload/26908557.zip');
header("Content-Type: application/Zip");
header("Content-Disposition: attachment; filename=26908557.zip");
header("Content-Length: " . filesize('C:/xampp/htdocs/issv/upload/26908557.zip'));
readfile('C:/xampp/htdocs/issv/upload/26908557.zip');
exit;
that's my code and it only works that way, but I want to put the $direccion path to it
$direccion='c:/xampp/htdocs/issv/upload/'.trim($cedula);
this is what my variable $cédula means $cedula=$_POST['cedula'];
There many ways of zip file creation which are;
$zip_file = '(path)/filename.zip';$dir = plugin_dir_path( __FILE__ );
$zip_file = $dir . '/filename.zip';$zip = new ZipArchive();
if ( $zip->open($zip_file, ZipArchive::CREATE) !== TRUE) {
exit("message");
} $zip->addFile('full_path_of_the_file', 'custom_file_name); $download_file = file_get_contents( $file_url );
$zip->addFromString(basename($file_url),$download_file); $zip->close();
Or simply do this:
$url = "http://anysite.com/file.zip";$zip_file = "folder/downloadfile.zip";$zip_resource = fopen($zipFile, "w");$ch_start = curl_init();curl_setopt($ch_start, CURLOPT_URL, $url);curl_setopt($ch_start,CURLOPT_FAILONERROR, true);curl_setopt($ch_start,CURLOPT_HEADER, 0);curl_setopt($ch_start,CURLOPT_FOLLOWLOCATION, true);curl_setopt($ch_start,CURLOPT_AUTOREFERER, true);curl_setopt($ch_start,CURLOPT_BINARYTRANSFER,true);curl_setopt($ch_start,CURLOPT_TIMEOUT, 10);curl_setopt($ch_start,CURLOPT_SSL_VERIFYHOST, 0);curl_setopt($ch_start,CURLOPT_SSL_VERIFYPEER, 0);curl_setopt($ch_start,CURLOPT_FILE,$zip_resource);$page =curl_exec($ch_start);if(!$page){echo "Error :- ".curl_error($ch_start);}curl_close($ch_start);$zip = new ZipArchive;$extractPath = "Download File Path";if($zip->open($zipFile) != "true"){echo "Error :- Unable to open the Zip File";}$zip->extractTo($extractPath);$zip->close();
class FileNotFound extends RuntimeException {}
$downloadUploadedZip = function(string $filename): void {
$directory = 'C:/xampp/htdocs/issv/upload';
if (dirname($filename) !== '.') {
$directory = dirname($filename);
}
$filename = basename($filename);
$filepath = sprintf('%s/%s', $directory, $filename);
if (file_exists($filepath)) {
header("Content-Type: application/zip");
header(sprintf("Content-Disposition: attachment; filename=%s", $filename));
header(sprintf("Content-Length: %d", filesize($filepath)));
readfile($filepath);
exit;
}
throw new FileNotFound(sprintf('File %s not found.', $filepath));
};
$downloadUploadedZip('26908557.zip');
$downloadUploadedZip('C:/xampp/htdocs/issv/upload/26908557.zip');
The code I currently have, attached below, successfully writes files into an archive and initiates downloading of the file but the filename is a random alphanumeric string. A few examples of these file titles are:
IfTO57y8.zip
PFuuPgMD.zip
KUgWDc0T.zip
How can I set the name of the Zip folder to something more user-friendly?
function start_brochures_download( $brochures ) {
$confirmation = "Your download should begin shortly. \r\n";
$error = "Files not set \r\n";
$files = $brochures;
if( $files ) {
$zip = new ZipArchive();
$current_time = time();
$file_name = "Brochures-".$current_time;
$file_folder = wp_upload_dir();
$dir = $file_folder['path'];
$zip_file = $dir.'/'.$file_name.'.zip';
$zip->open( $zip_file, ZipArchive::CREATE );
foreach ($files as $file) {
if( !empty($file) ){
# download file
$download_file = file_get_contents($file);
#add it to the zip
$zip->addFromString(basename($file), $download_file);
}
}
$zip->close();
header('Content-disposition: attachment; filename="'.$zip_name.'"');
header('Content-type: application/zip');
header('Content-Length: ' . filesize($zip_file));
// header("Location: $zip_file");
readfile($zip_file);
} else {
echo $error;
}
}
I posted my code a few days back and I am now at this point with it. I have acquired the random files however, when they zip it becomes a zip.cpgz file after unzipping. I am sure that this has something to do with the way I used array in my loop but I am not quite sure of how to fix this.
<?php
//./uploads
$dir = "./uploads";
$nfiles = glob($dir.'*.{aiff}', GLOB_BRACE);
$n=1;
while ($n<=10){
$n ++;
$arr[$n] = rand(2, sizeof($nfiles)-1);
print($arr[$n]);
print(" ");
}
$zip = new ZipArchive();
$zip_name = "zipfile.zip";
if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE){
$error .= "* Sorry ZIP creation failed at this time";
}
foreach($arr as $file){
$path = "./uploads".$file;
$zip->addFromString(basename($path), file_get_contents($path));
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zip_name);
readfile('zipfile.zip');
?>
Also if you are kinda lost here is my website I am trying to implement it on. (click the download button)
Recently helped another user get something similar to work ( without the random selection ) and you might find the following useful. This does search a directory for a particular file extension and then randomly select 10 files which get zipped and sent. Change the $sourcedir and $ext to suit - hope it helps.
/* From David Walsh's site - modified */
function create_zip( $files = array(), $destination = '', $overwrite = false ) {
if( file_exists( $destination) && !$overwrite ) { return false; }
$valid_files = array();
if( is_array( $files ) ) {
foreach( $files as $file ) if( file_exists( $file ) ) $valid_files[] = $file;
}
if( count( $valid_files ) ) {
$zip = new ZipArchive();
if( $zip->open( $destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE ) !== true) return false;
foreach( $valid_files as $file ) $zip->addFile( $file, pathinfo( $file, PATHINFO_FILENAME ) );
$zip->close();
return file_exists( $destination );
}
return false;
}
/* Simple function to send a file */
function sendfile( $filename=NULL, $filepath=NULL ){
if( file_exists( $filepath ) ){
if( !is_file( $filepath ) or connection_status()!=0 ) return FALSE;
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime( date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Content-Type: application/octet-stream");
header("Content-Length: ".(string)( filesize( $filepath ) ) );
header("Content-Disposition: inline; filename={$filename}");
header("Content-Transfer-Encoding: binary\n");
if( $file = #fopen( $filepath, 'rb' ) ) {
while( !#feof( $file ) and ( connection_status()==0 ) ) {
print( fread( $file, 1024*8 ) );
flush();
}
#fclose( $file );
}
return( ( connection_status()==0 ) and !connection_aborted() );
}
}
/* Select a random entry from the array */
function pick( $arr ){
return $arr[ rand( 0, count( $arr )-1 ) ];
}
/* The directory to which the zip file will be written before sending */
$target=__DIR__.'\zipfile.zip';
/* The directory you wish to scan for files or create an array in some other manner */
$sourcedir = 'C:\Temp\temp_uploads';
/* File extension to scan for */
$ext='txt';
/* Placeholder to store files*/
$output=array();
/* Scan the dir, or as mentioned, create an array of files some other way */
$files=glob( realpath( $sourcedir ) . DIRECTORY_SEPARATOR . '*.'.$ext );
/* Pick 10 random files from all possible files */
do{
$rnd=pick( $files );
$output[ $rnd ] = $rnd;
}while( count( $output ) < 10 );
/* streamline array */
$output=array_values($output);
if( $target ) {
/* Zip the contents */
$result=create_zip( $output, $target, true );
/* Send the file - zipped! */
if( $result ) {
$res=call_user_func( 'sendfile', 'zipfile.zip', $target );
if( $res ) unlink( $target );
}
}
You sure it doens't work? I've donwloaded your zip file and extracted it and I got UploadsX files. So I don't get a zip.cpgz file.
This question already has answers here:
php creating zips without path to files inside the zip
(4 answers)
Closed 9 years ago.
My code creates a ZIP file and downloads it in this ZIP folder some images exist.
It’s done well but problem is that after I download and extract this folder then all path folder also become my code is:
$id = $row['id'];
$doc_name = $row['doc_name'];
$file_names = explode(',',$doc_name);
$file_path = $_ROOT_REQUIRE."uploads/document/";
$archive_file_name = "demo.zip";
$zip = new ZipArchive($archive_file_name);
if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE ) !== TRUE) {
echo "cannot open <$archive_file_name>\n";
exit("cannot open <$archive_file_name>\n");
}
foreach ($file_names as $files) {
if ($files !== '') {
$zip->addFile("$files", basename($files));
}
}
$zip->close();
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($archive_file_name).'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($archive_file_name));
header('Cache-Control: private');
ob_clean();
flush();
readfile(basename($archive_file_name));
exit;
Your Code look's is Fine.
Just Replace Your Foreach Loop .
foreach ($files as $file)
{
$file = str_replace('\\', '/', $file);
if(filetype($file) == 'file') {
$zip->addFile( $file, pathinfo( $file, PATHINFO_BASENAME ) );
}
}
it should be work
Thanks
A bit unclear on why this would be happening, looking at this line:
$zip->addFile("$files", basename($files));
Why are there " quotes around $files? I would recommend changing that to:
$zip->addFile($files, basename($files));
These are the changes I made and it work well now. Thanks to all.
$overwrite = true;
if($zip->open($archive_file_name,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true)
This larger piece:
foreach ($file_names as $file) {
$files = $file_path.$file;
$files = str_replace('\\', '/', $files);
if(filetype($files) == 'file') {
$zip->addFile( $files, pathinfo( $files, PATHINFO_BASENAME ) );
}
}
I am trying to make file download script that collection all the files and download a zip file that has that collection of files not all the directory structure..
i have the file in download/folder1/folder1/filename.extension
here is my PHP codes:
if( !extension_loaded('zip') ){
echo "<script>alert('Error: Please contact to the Server Administrator!');</script>";
exit;
}
$zip = new ZipArchive;
if( $zip->open($zipname, ZipArchive::OVERWRITE) === TRUE ){
foreach( $files as $file ){
$zip->addFile( BASE_PATH.$file_path.'/'.$file, $file );
}
$zip->close();
} else {
echo "<script>alert('Error: problem to create zip file!');</script>";
exit;
}
this code gives me the structure like this:
it gives the complete path of wamp(including the path director and files) and the files, i just want to add the files not the directory..
Can someone tell me what i missed??
Every time download link comes with the unique download key, i just add the unique_key with the name of download.zip file and its working...
// $db_secret_key Random Unique Number
$zipname = $db_secret_key."_download.zip";
if( !extension_loaded('zip') ){
echo "<script>alert('Error: Please contact to the Server Administrator!');</script>";
exit;
}
$zip = new ZipArchive;
if( $zip->open($zipname, ZipArchive::CREATE) === TRUE ){
foreach( $files as $file ){
$zip->addFile( BASE_PATH.$file_path.'/'.$file, $file );
}
$zip->close();
// Force Download
header("Content-Type: application/zip");
header("Content-disposition: attachment; filename=$zipname");
header("Content-Length: ".filesize($zipname)."");
header("Pragma: no-cache");
header("Expires: 0");
readfile($zipname);
exit;
} else {
echo "<script>alert('Error: problem to create zip file!');</script>";
exit;
}