Do not remove duplicate values from array - php

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

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

How to create a ZIP file with PHP

I try to create a ZIP file with PHP. Inside this ZIP files I want to add multiple PDF files.
My code
$actual_link = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$parts = parse_url($actual_link);
parse_str($parts['query'], $query);
$downloads = json_decode($query["downloads"]);
$files = array();
foreach ($downloads as $download) {
array_push($files, "https://website.com/downloads/". $download->value .".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="test.zip"');
header('Content-type: application/zip');
readfile($tmp_file);
unlink($tmp_file);
The ZIP file downloads fine, but my PDF files have 0kb and no content....
Do you find the error?

Set the name of Zip archive using ZipArchive class

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

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

PHP Create Multiple CSV Files in Memory then Compress

I have a requirement to create 3 CSV files (in memory) during a single HTTP request, ZIP the files into a single compressed file and return the compressed file as a HTTP response.
I have the following code to create the zip file...
$files = array($file1, $file2);
$zipname = 'file.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);
However, I don't know how to create the CSV files in memory.
How can I achieve this?
Try this...
// some data to be used in the csv files
$headers = array('id', 'name', 'age', 'species');
$records = array(
array('1', 'gise', '4', 'cat'),
array('2', 'hek2mgl', '36', 'human')
);
// create your zip file
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
// loop to create 3 csv files
for ($i = 0; $i < 3; $i++) {
// create a temporary file
$fd = fopen('php://temp/maxmemory:1048576', 'w');
if (false === $fd) {
die('Failed to create temporary file');
}
// write the data to csv
fputcsv($fd, $headers);
foreach($records as $record) {
fputcsv($fd, $record);
}
// return to the start of the stream
rewind($fd);
// add the in-memory file to the archive, giving a name
$zip->addFromString('file-'.$i.'.csv', stream_get_contents($fd) );
//close the file
fclose($fd);
}
// close the archive
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
// remove the zip archive
// you could also use the temp file method above for this.
unlink($zipname);
I've just tested this on my machine and it works fine.
I used this link as a reference, It may be useful.
MetaShock Reference
You can use php's memory wrapper:
$zipname = 'php://memory';
On systems having /dev/shm filesystem you can create files there, they will be kept only in memory and only accessible to current process. Don't forget to remove them after sending, web server process will keep running.

Categories