Creating zipped file of many pdfs automatically - php

I am trying to zip a series of pdf files automatically when a page loads. The files are based on a query. I can't seem to figure out the error. All of the pdfs are kept in the agreements folder and I want the zip file to just download on the viewer's computer. The error code that I get is:
agreements/Acadience_Cambridge_Post_1.pdfagreements/DoTheMath_Cambridge.pdfagreements/Edulog_Cambridge.pdfagreements/DESSA_Cambridge.pdfagreements/FuelEducation_Cambridge_signed.pdfagreements/LegendsofLearning_Dedham.pdfagreements/workforce19-22.pdfagreements/Ellevation_Dedham_Posting.pdfagreements/Yabla_Cambridge.pdfagreements/Breakthrough-2020.pdfagreements/Cedar-Labs-DPA.pdfagreements/Tutoring Plus.pdfagreements/Elefante Letrado_Brockton - post.pdfagreements/CollegeBoard_Cambridge_post_1.pdfagreements/LanguageConnections_post.pdfagreements/Flat_Westford - post.pdfagreements/Albert.io_Cambridge_post.pdfagreements/Starfall_Walpole.pdfagreements/Tynker_Milton - post_1.pdfagreements/WeVideo_CambridgeTEC_1.pdfagreements/Checkology_Dedham.pdfagreements/BabylonHouse _Cambridge_signed_4.pdfagreements/FreeMath_Westwood_Post.pdf
Warning: ZipArchive::close(): Failure to create temporary file: Permission denied in /var/www/html/extract_dpas2.php on line 36
Could not find Zip file to download
Here is the code I have:
<?php require_once('Connections/sdpc_i.php'); ?>
<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
$sql = "SELECT * FROM data WHERE districtID = 457 and statusID=1 and signed_agreement_file != 'NULL'";
if ($result=mysqli_query($sdpc_i,$sql))
{
// $rowcount=mysqli_num_rows($result);
// printf("Result set has %d rows.\n",$rowcount);
//define array for storing files
$file = array();
while ($row = mysqli_fetch_assoc($result)) {
//give file name with extension
$name ="agreements/".$row['signed_agreement_file'];
//store file name in array
$file[] = $name;
// store file in one folder named 'files'
file_put_contents($name,$row["signed_agreement_file"]);
}
$zipname = "file.zip";
$zip = new ZipArchive();
$zip_name = time().".zip"; // Zip name
$zip->open($zip_name, ZipArchive::CREATE);
foreach ($file as $f) {
echo $path = "".$f;
if(file_exists($path)){
$zip->addFromString(basename($path), file_get_contents($path));
}
else{
echo"file does not exist";
}
}
$zip->close();
//check zip file create or not and download it
if (file_exists($zipname)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($zipname).'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($zipname));
ob_clean();
flush();
readfile($zipname);
exit;
} else {
exit("Could not find Zip file to download");
}
mysqli_free_result($result);
mysqli_close($conn);
}
?>
Thank you in advance for you help.

Related

Download a zip file of blobs (from database) as images to my local storage using PHP

I have a form from which, we get the data from users. Images are stored as blob in database. Now, I want all of the responded images to my local storage (computer).
<?php
include 'config.php';
session_start();
$table_name = $_SESSION["table"];
$zip = new ZipArchive();
$ZipFileName = $table_name . '.zip';
if ($zip->open($ZipFileName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true) {
echo "Cannot Open";
}
$zip->addEmptyDir('newFolder');
$query = mysqli_query($con, "SELECT * FROM $table_name");
while($row = mysqli_fetch_assoc($query)) {
$temp = $row['student_id'] . '.jpg';
$zip->addFromString($temp, $row['photo']);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=' . $ZipFileName);
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-length: " . filesize($ZipFileName));
?>
Zip file is downloaded, but at the time of extraction it shows error. When I tried to download only one image it shows no preview.
How can I download all the blob files as images to my computer (a zip file)?

php add file to zip returning blank files

I am having an issue with the below code (it works fine on local).
I am using this for an image gallery to download a selection of images using a checkbox. Anyways, this is working fine on my localhost but when I execute this code on my live site it downloads a zip file with the correct file names but the the files are blank.
Any suggestions to why this may be happening?
<?php
function zipFilesAndDownload($file_names, $archive_file_name, $file_path)
{
$zip = new ZipArchive();
//create the file and throw the error if unsuccessful
if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE) !== true) {
exit("cannot open <$archive_file_name>\n");
}
foreach ($file_names as $files) {
# download file
$download_file = file_get_contents($files);
#add it to the zip
$zip->addFromString(basename($files), $download_file);
}
$zip->close();
$zipped_size = filesize($archive_file_name);
header("Content-Description: File Transfer");
header("Content-type: application/zip");
header("Content-Type: application/force-download");// some browsers need this
header("Content-Disposition: attachment; filename=$archive_file_name");
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-Length:" . " $zipped_size");
ob_clean();
flush();
readfile("$archive_file_name");
unlink("$archive_file_name"); // Now delete the temp file on the server
exit;
}
if (isset($_POST['formSubmit'])) {
//$file_names=$_POST['files'];//
//$file_names = filter_var_array($_POST['files']);//works but it's the wrong method
$filter = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS); //sanitise files
$file_names = $filter['files'];
//Archive name
$archive_file_name = 'product-images.zip';
//Download Files path
$file_path = getcwd() . '';
//cal the function
zipFilesAndDownload($file_names, $archive_file_name, $file_path);
} else {
header("Refresh: 5; url= ./index.php ");
print '<h1 style="text-align:center">You you shouldn\'t be here ......</pre>
<p style="color: red;"><strong>redirection in 5 seconds</strong></p>
<pre>';
exit;
}
?>
edit: i see this in my php error log:
PHP message: PHP Warning: ZipArchive::close(): Failure to create temporary file: Permission denied in /var/www/html/wp-content/plugins/jig/download-product-images.php on line 19

Unable To Create zip for multiple large files and unlink the zip

I am trying to download some files from server using a php script but when I execute the script it works fine with smaller number of file with lesser number of files to zip however when I try execution with larger no of files the server times out and also the zip generated as the result is not deleted and occupies the space on server. the php script is as follows
if(isset($_POST['download_all']))
{
$errmsg = '';
$sql = mysqli_query($conn, "select * from img WHERE gal_id = '".base64_decode($_REQUEST['Gal'])."' And uid='".$_SESSION['uid']."' order by image1 asc");
$url = "dataroot/Gallery/".base64_decode($_REQUEST['Gal'])."_".$_SESSION['uid']."/";
while($res = mysqli_fetch_array($sql)){
$filess[] = $url.$res['image1'];
echo $url.$res['image1'];
}
$files = json_encode($filess);
$files = json_decode($files);
if(is_array($files)) {
foreach($files as $file) {
if(file_exists($file)) {
$valid_files[] = $file;
}
}
}
if(count($valid_files > 0)){
$zip = new ZipArchive();
$zip_name = "total.zip";
if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE){
$error .= "* Sorry ZIP creation failed at this time";
}
foreach($valid_files as $file){
$zip->addFile($file);
}
$zip->close();
if(file_exists($zip_name)){
// force to download the zip
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Transfer-Encoding: binary");
header("Content-length: $ size");
header("Cache-Control: private",false);
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
ob_clean();
flush();
readfile($zip_name);
ignore_user_abort(true);
//remove zip file from temp path
unlink($zip_name);
}
} else {
echo "No valid files to zip";
exit;
}
}
I have updated the memory and timeout setting on the server. The issue persists. Also the zip thus formed as the result is not unlinked and consumes memory on server.
already referred to
Reading very large files in PHP
and
How to download multiple large files with php?
but unable to resolve the issue.

Can create zip archive in PHP, but cannot download it correctly

I'm working on a CodeIgniter-based web app, and I'm implementing the functionality to download a zip file of the vehicle images in the admin for passing to third parties.
I'm able to create the zip archive without problem - if I comment out the later parts, I can see that the zip file gets created and contains the correct files, and it can be extracted as normal.
However, allowing the user to download the file once it's created is proving tricky. What I've implemented allows a file with the correct name to be downloaded, but it errors when unzipped with the following message:
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
Any idea where I've gone wrong? I checked multiple tutorials on the web and couldn't find where the issue was.
public function downloadvehicleimages()
{
// If logged in...
if ($this->adminuser)
{
// Get data
$usedcars = $this->adminmodel->getUsedCarsWithLimit();
// Get the registrations for these vehicles
$registrations = array();
foreach($usedcars->result_array() as $usedcar)
{
array_push($registrations, $usedcar['Registration']);
}
// Get all the images for these registrations
$images = array();
$original_dir = getcwd();
chdir('../used-cars/static/images/custom/');
foreach($registrations as $registration)
{
$vehicle_images = glob(strtoupper($registration) . '_*.jpg');
sort($vehicle_images);
foreach($vehicle_images as $vehicle_image)
{
array_push($images, $vehicle_image);
}
}
// Zip them up
$zipname = 'images.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach($images as $image)
{
$zip->addFile($image);
}
$zip->close();
// Let user download the file
$this->output->set_header('Content-Type: application/zip');
$this->output->set_header('Pragma: no-cache');
$this->output->set_header('Expires: 0');
$this->output->set_header("Content-Disposition: attachment;filename='$zipname'");
$this->output->set_header('Content:Length: ' . filesize($zipname));
unlink($zipname);
chdir($original_dir);
}
}
You need to use fopen() to read the content of the zipfile, and readfile() to pass the file content to the visitor. And also, provide the full system directory uri to the files location:
$filename = 'images.zip';
$path = /var/www/yourdomain.com/images.zip';
if(!file_exists($path))
{
die('Error: file not found');
}
else {
$handle = fopen($path, "r");
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
flush();
readfile($path);
fclose($handle);

Zipping checkboxed files PHP

<?PHP
function zipFilesAndDownload($file_names,$archive_file_name,$file_path){
$zip = new ZipArchive();
//create the file and throw the error if unsuccessful
if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE )!==TRUE) {
exit("cannot open <$archive_file_name>\n");
}
//add each files of $file_name array to archive
foreach($file_names as $files) {
$zip->addFile($file_path.$files,$files);
}
$zip->close();
$zipped_size = filesize($archive_file_name);
header("Content-Description: File Transfer");
header("Content-type: application/zip");
header("Content-Type: application/force-download");// some browsers need this
header("Content-Disposition: attachment; filename=$archive_file_name");
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-Length:". " $zipped_size");
ob_clean();
flush();
readfile("$archive_file_name");
unlink("$archive_file_name"); // Now delete the temp file (some servers need this option)
exit;
}
if(($_POST['formSubmit'])) {
//$file_names=$_POST['items'];// Always sanitize your submitted data!!!!!!
//$file_names = filter_var_array($_POST['items']);//works but it's the wrong method
$filter = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS) ;
$file_names = $filter['items'] ;
//Archive name
$archive_file_name= "zip.zip";
//Download Files path
$file_path= $leadon;
//cal the function
zipFilesAndDownload($file_names,$archive_file_name,$leadon);
}
?>
I have a working code here.
The main problem is
//Download Files path
$file_path= $leadon;
//cal the function
zipFilesAndDownload($file_names,$archive_file_name,$leadon);
This code
echo $leadon;
returns string images2/User/
And it doesn't create me the zip file ( well it creates a blank ) but if I manually type in the path
"images2/User/"
into
$file_path= and then I just change
zipFilesAndDownload($file_names,$archive_file_name,$file_path);
everything works fine can you tell me why is it so? And how can I change it:s

Categories