Set the name of Zip archive using ZipArchive class - php

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

Related

Fetch everything in a folder based on extension and put into zip

I have to make 3 buttons. On button click I want to download all files from selected folder with correct extension in zip file. Eveything on wordpress site. The problem is, zip file is saving as .zip, but when I open it in notepad, there's HTML code. Thanks for help!
<?php
if(isset($_POST['3dsdownload'])) {dddownloads();}
function dddownloads(){
$dir = realpath("/autoinstalator/wordpress/wp-content/uploads/");
$scan_arr = scandir($dir);
$zip = new ZipArchive();
$zip->open('3ds.zip', ZipArchive::CREATE);
$files = array_diff($scan_arr, array('.','..') );
foreach ($files as $name => $file) {
if (!is_dir($file)){
$filePath = $dir.$file;
$file_ext = pathinfo($filePath, PATHINFO_EXTENSION);
if ($file_ext=="3ds" || $file_ext=="3DS") {
$zip->addFile($filePath, basename($filePath));
}
}
}
$zip->close();
header('Content-disposition: attachment; filename=3ds.zip');
header('Content-type: application/zip');
readfile('3ds.zip');
exit;
}
?>
<form method="post">
<input type="submit" name="3dsdownload"
value="3dsdownload"/>
</form>
The problem was buffer and path. After adding ob_clean() and fixing path, everything works fine! Final code:
<?php //Strona z pobieraniem wszystkich plikow z podziałem na formaty
//3ds
if(isset($_POST['3dsdownload'])) {dddownloads();}
function dddownloads(){
ob_clean();
$dir = (dirname(__DIR__,2)."/uploads/");
$scan_arr = scandir($dir);
$zip = new ZipArchive();
$zip->open('3ds.zip', ZipArchive::CREATE | ZIPARCHIVE::OVERWRITE);
$files = array_diff($scan_arr, array('.','..') );
foreach ($files as $name => $file) {
if (!is_dir($file)){
$filePath = $dir.$file;
$file_ext = pathinfo($filePath, PATHINFO_EXTENSION);
if ($file_ext=="3ds" || $file_ext=="3DS") {
$zip->addFile($filePath, basename($filePath));
}
}
}
$zip->close();
header('Content-disposition: attachment; filename=3ds.zip');
header('Content-type: application/zip');
header("Content-Transfer-Encoding: binary");
ob_end_clean();
readfile('3ds.zip');
exit;
}
?>

Download Zip file in php

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

Do not remove duplicate values from array

I have written this code to download files after adding them in a zip file. However, my code removes the files which have the same name ( duplicate ).
<?php
# define file array
$files = array(
'https://www.fbise.edu.pk/Old%20Question%20Paper/2017/SSC-II/Chemistry.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2018/SSC-II/Chemistry.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2018/SSC-II/Physics.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2017/SSC-II/Physics.PDF',
);
# create new zip object
$zip = new ZipArchive();
# create a temp file & open it
$tmp_file = tempnam('.', '');
$zip->open($tmp_file, ZipArchive::CREATE);
# loop through each file
foreach ($files as $file) {
# download file
$download_file = file_get_contents($file);
#add it to the zip
$zip->addFromString(basename($file), $download_file);
}
# close zip
$zip->close();
# send the file to the browser as a download
header('Content-disposition: attachment; filename="my file.zip"');
header('Content-type: application/zip');
readfile($tmp_file);
unlink($tmp_file);
?>
So my question is,
How can I download duplicate files from an array?
or
How can I change the names of duplicate files?
Just rename your files.
<?php
# define file array
$files = array(
'https://www.fbise.edu.pk/Old%20Question%20Paper/2017/SSC-II/Chemistry.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2018/SSC-II/Chemistry.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2018/SSC-II/Physics.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2017/SSC-II/Physics.PDF',
);
# create new zip object
$zip = new ZipArchive();
# create a temp file & open it
$tmp_file = tempnam('.', '');
$zip->open($tmp_file, ZipArchive::CREATE);
// Variable to Keep Filenames
$filename = '';
// Variable to add "-1, -2" to duplicate files
$i = 1;
# loop through each file
foreach ($files as $file) {
# download file
$download_file = file_get_contents($file);
if ( $filename == basename($file) )
{
// If this file already exists add "-1, -2"
$filename = $i . '-' . basename($file);
$i++;
} else
{
$filename = basename($file);
$i = 1;
}
#add it to the zip
$zip->addFromString($filename, $download_file);
}
# close zip
$zip->close();
# send the file to the browser as a download
header('Content-disposition: attachment; filename="my file.zip"');
header('Content-type: application/zip');
readfile($tmp_file);
unlink($tmp_file);
?>
Edit after #RiggsFolly Comment to support out of order duplicate files
<?php
# define file array
$files = array(
'https://www.fbise.edu.pk/Old%20Question%20Paper/2017/SSC-II/Chemistry.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2018/SSC-II/Chemistry.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2018/SSC-II/Physics.PDF',
'https://www.fbise.edu.pk/Old%20Question%20Paper/2017/SSC-II/Physics.PDF',
);
# create new zip object
$zip = new ZipArchive();
# create a temp file & open it
$tmp_file = tempnam('.', '');
$zip->open($tmp_file, ZipArchive::CREATE);
// Array to keep filenames
$filenames = array();
# loop through each file
foreach ($files as $file) {
# download file
$download_file = file_get_contents($file);
if( array_key_exists( basename($file), $filenames ) )
{
$filename = $filenames[basename($file)] . '-' . basename($file);
$filenames[basename($file)] = $filenames[basename($file)] + 1;
} else
{
$filename = basename($file);
$filenames[basename($file)] = 1;
}
#add it to the zip
$zip->addFromString($filename, $download_file);
}
# close zip
$zip->close();
# send the file to the browser as a download
header('Content-disposition: attachment; filename="my file.zip"');
header('Content-type: application/zip');
readfile($tmp_file);
unlink($tmp_file);
?>

How to create zip file from a large folder using Codeigniter and PHP?

I'm trying to create zip file from a large folder which size almost 2GB. My code is working well on the localhost but it's not working on the server(Cpanel). In server, it's creating a zip file which size is only 103 MB out of 2GB. According to my strategy, first of all, I'm creating a backup folder recursively named "system_backup". And the backup folder is creating well without any problem. The next is, to create the zip file of 'system_backup' folder by calling the function ZipData and stored it to another folder. In this time, it's not creating the zip file properly.
After that, the function rrmdir will be called. And it will delete the 'system_backup' folder recursively. And the deletion is not working properly as well. And, in localhost, it works well.
Then, when I'm trying to download the created zip file by the function download_file, it also not download properly. It's downloaded as a broken zip file. And, in localhost, it also works well.
I have already checked the read and write permission of folders and files.
The code is given below:-
public function backup_app(){
//Backup System
ini_set('memory_limit', '-1');
set_time_limit(0);
$this->recurse_copy(FCPATH,'system_backup');
$backup_name = 'Customs-system-backup-on_'. date("Y-m-d-H-i-s") .'.zip';
$path = FCPATH.'system_backup';
$destination = FCPATH.'bdCustomsBackup/'.$backup_name;
$this->zipData($path, $destination);
//Delete directory
$this->rrmdir($path);
$message = "Application Backup on ".date("Y-m-d-H-i-s");
$this->submit_log($message);
echo 1;
}
function zipData($source, $destination) {
if (extension_loaded('zip')) {
if (file_exists($source)) {
$zip = new ZipArchive();
if ($zip->open($destination, ZIPARCHIVE::CREATE)) {
$source = realpath($source);
if (is_dir($source)) {
$iterator = new RecursiveDirectoryIterator($source);
// skip dot files while iterating
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
$counter = 1;
foreach ($files as $file) {
$file = realpath($file);
if (is_dir($file)) {
$zip->addEmptyDir(str_replace($source . '/', 'system_backup/', $file . '/'));
} else if (is_file($file)) {
$zip->addFromString(str_replace($source . '/', 'system_backup/', $file), file_get_contents($file));
}
}
} else if (is_file($source)) {
$zip->addFromString(basename($source), file_get_contents($source));
}
}
return $zip->close();
}
}
return false;
}
public function recurse_copy($src,$dst) {
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' ) && ( $file != $dst ) && ( $file != "bdCustomsBackup" )) {
if ( is_dir($src . '/' . $file) ) {
$this->recurse_copy($src . '/' . $file, $dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
public function rrmdir($src) {
$dir = opendir($src);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
$full = $src . '/' . $file;
if ( is_dir($full) ) {
$this->rrmdir($full);
}
else {
unlink($full);
}
}
}
closedir($dir);
rmdir($src);
}
public function download_file($file){
$message = "Download ".$file." on ".date("Y-m-d-H-i-s");
$this->submit_log($message);
$path = FCPATH.'bdCustomsBackup/'.$file;
$this->load->helper('download_helper');
force_download($file, $path);
}
Here is the custom download_helper:-
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('force_download'))
{
function force_download($filename = '', $file = '')
{
if ($filename == '' OR $file == '')
{
return FALSE;
}
// Try to determine if the filename includes a file extension.
// We need it in order to set the MIME type
if (FALSE === strpos($filename, '.'))
{
return FALSE;
}
// Grab the file extension
$x = explode('.', $filename);
$extension = end($x);
// Load the mime types
#include(APPPATH.'config/mimes'.EXT);
// Set a default mime if we can't find it
if ( ! isset($mimes[$extension]))
{
$mime = 'application/octet-stream';
}
else
{
$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
// Generate the server headers
if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".filesize($file));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".filesize($file));
}
readfile_chunked($file);
die;
}
}
if ( ! function_exists('readfile_chunked'))
{
function readfile_chunked($file, $retbytes=TRUE)
{
$chunksize = 1 * (1024 * 1024);
$buffer = '';
$cnt =0;
$handle = fopen($file, 'r');
if ($handle === FALSE)
{
return FALSE;
}
while (!feof($handle))
{
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes)
{
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes AND $status)
{
return $cnt;
}
return $status;
}
}
/* End of file download_helper.php */
/* Location: ./application/helpers/download_helper.php */
The below code is using PHP:
$zip = new ZipArchive;
if ($zip->open('test_new.zip', ZipArchive::CREATE) === TRUE)
{
// Add files to the zip file
$zip->addFile('test.txt');
$zip->addFile('test.pdf');
// Add random.txt file to zip and rename it to newfile.txt
$zip->addFile('random.txt', 'newfile.txt');
// Add a file new.txt file to zip using the text specified
$zip->addFromString('new.txt', 'text to be added to the new.txt file');
// All files are added, so close the zip file.
$zip->close();
}
Explanation of code
Line 1 creates an object of the ZipArchive class
Line 2 opens a file with filename as test_new.zip so that we can add files to it. The flag ZipArchive::CREATE specifies that we want to create a new zip file
Lines 5 & 6 are used to add files to the zip file
Line 9 is used to add a file with name random.txt to the zip file and rename it in the zipfile as newfile.txt
Line 12 is used to add a new file new.txt with contents of the file as ‘text to be added to the new.txt file’
Line 15 closes and saves the changes to the zip file
Note: Sometimes there can be issues when using relative paths for files. If there are any issues using paths then we can also use absolute paths for files
Overwrite an existing zip file
If you want to overwrite an existing zip file then we can use code similar to following. The flag ZipArchive::OVERWRITE overwrites the existing zip file.
$zip = new ZipArchive;
if ($zip->open('test_overwrite.zip', ZipArchive::OVERWRITE) === TRUE)
{
// Add file to the zip file
$zip->addFile('test.txt');
$zip->addFile('test.pdf');
// All files are added, so close the zip file.
$zip->close();
}
Explanation of code
This code will create a file test_overwrite.zip if it already exists the file will be overwritten with this new file
Create a new zip file and add files to be inside a folder
$zip = new ZipArchive;
if ($zip->open('test_folder.zip', ZipArchive::CREATE) === TRUE)
{
// Add files to the zip file inside demo_folder
$zip->addFile('text.txt', 'demo_folder/test.txt');
$zip->addFile('test.pdf', 'demo_folder/test.pdf');
// Add random.txt file to zip and rename it to newfile.txt and store in demo_folder
$zip->addFile('random.txt', 'demo_folder/newfile.txt');
// Add a file demo_folder/new.txt file to zip using the text specified
$zip->addFromString('demo_folder/new.txt', 'text to be added to the new.txt file');
// All files are added, so close the zip file.
$zip->close();
}
Explanation of code
The above code will add different files inside the zip file to be inside a folder demo_folder
The 2nd parameter to addfile function can be used to store the file in a new folder
The 1st parameter in the addFromString function can be used to store the file in a new folder
Create a new zip file and move the files to be in different folders
$zip = new ZipArchive;
if ($zip->open('test_folder_change.zip', ZipArchive::CREATE) === TRUE)
{
// Add files to the zip file
$zip->addFile('text.txt', 'demo_folder/test.txt');
$zip->addFile('test.pdf', 'demo_folder1/test.pdf');
// All files are added, so close the zip file.
$zip->close();
}
Explanation of code
We store the file test.txt into demo_folder and test.pdf into demo_folder1
Create a zip file with all files from a directory
$zip = new ZipArchive;
if ($zip->open('test_dir.zip', ZipArchive::OVERWRITE) === TRUE)
{
if ($handle = opendir('demo_folder'))
{
// Add all files inside the directory
while (false !== ($entry = readdir($handle)))
{
if ($entry != "." && $entry != ".." && !is_dir('demo_folder/' . $entry))
{
$zip->addFile('demo_folder/' . $entry);
}
}
closedir($handle);
}
$zip->close();
}
Explanation of code
Lines 5-16 opens a directory and creates a zip file with all files within that directory
Line 5 opens the directory
Line 7 gets the name of each file in the dir
Line 9 skips the “.” and “..” and any other directories
Line 11 adds the file into the zip file
Line 14 closes the directory
Line 17 closes the zip file

php downloaded files in zip are empty

currently I am trying to put files in a zip and download them. I use the following code:
# create new zip opbject
$zip = new ZipArchive();
# create a temp file & open it
$tmp_file = tempnam('.','');
$zip->open($tmp_file, ZipArchive::CREATE);
# loop through each file
foreach($files as $file){
# download file
$download_file = file_get_contents($file);
#add it to the zip
$zip->addFromString(basename($file),$download_file);
}
# close zip
$zip->close();
# send the file to the browser as a download
header('Content-disposition: attachment; filename=Resumes.zip');
header('Content-type: application/zip');
readfile($tmp_file);
The files are added to the array the following way:
$weborder = $_POST['weborder'];
$printlocation = $_POST['print'];
$dir = "z:\Backup\\$printlocation\\$weborder.zip";
$zip = new ZipArchive;
$files = array();
if ($zip->open($dir))
{
for($i = 0; $i < $zip->numFiles; $i++)
{
if ($zip->getNameIndex($i) != "order-info.txt" && $zip->getNameIndex($i) != "workrequest.xml" && $zip->getNameIndex($i) != "workrequest.pdf")
{
$filename = $zip->getNameIndex($i);
$files[$i] = $dir . "\\" . $filename;
}
}
}
This downloads the zip and the files that are in the zip. The only problem I am having is that the files are empty.
instead of
$zip->addFromString(basename($file),$download_file);
try
$zip->addFile($basename($file));
This code is working make sure that your files are existed or not.
$array = array("sites/README.txt","sites/chessboard.jpg"); //files to Add/Create in zip file
$zip = new ZipArchive(); // Load zip library
$zip_name = time().".zip"; // Zip name
if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE)
{
// Opening zip file to load files
$error .= "* Sorry ZIP creation failed at this time";
}
foreach($array as $key => $value)
{
if(file_exists($value)){
$zip->addFile($value); // Adding files into zip
}else{echo $value ." file not exist<br/>";}
}
$zip->close();
if(file_exists($zip_name))
{
echo "yes";die;
// push to download the zip
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
readfile($zip_name);
// remove zip file is exists in temp path
unlink($zip_name);
}else{echo "zip not created";die; }
For Download Existing file
$zip_name = "YOUR_ZIP_FILE PATH";
if(file_exists($zip_name))
{
// push to download the zip
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
readfile($zip_name);
// remove zip file is exists in temp path
//unlink($zip_name);
}else{
echo "zip not created";exit;
}

Categories