PHP Zip unable to close() - php

I'm trying to get a couple files from wordpress /uploads folder using php and I get this error:
Warning: ZipArchive::close(): Can't remove file: No such file or directory in /www/public_html/wp-content/plugins/insert-php-code-snippet/shortcode-handler.php(65) : eval()'d code on line 32 (relative to $zip->close(); and bellow "if")
I use a plugin to inject PHP on the page.
I basically have a couple dozens checkboxes that when I press "Generate", it gets the name of the file like 07/2019/blabla (with code I get uploads folder + extension, checkbox only hold the media location + name file).
I checked and it's creating the Zip on /uploads, .pdf files exist but it crashes on the close part and when I download and try to extract I get the archive is either in unknown format or damaged
Any advise please?
if(isset($_POST['files'])) {
$error = ""; //error holder
$upload_dir = wp_upload_dir();
if(isset($_POST['createzip'])){
$post = $_POST;
if(isset($post['files']) and count($post['files']) > 0){
// open zip
$zip_file = $upload_dir['basedir'].'/'.time().".zip";
$zip_name = time().".zip";
$zip = new ZipArchive();
if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== TRUE) {
$error .= ("An error occurred creating your ZIP file.<br>");
}
foreach ($post['files'] as $file) {
// generate filename to add to zip
$filepath = $upload_dir['basedir'].'/' . $file . '.pdf';
if (file_exists($filepath)) {
$zip->addFile($filepath) or $error .= ("ERROR: Could not add the file $filename<br>");
} else {
$error .= ("File $filepath doesnt exit.<br>");
}
}
$zip->close();
if ($zip->close() !== true ) {
die($zip->getStatusString()."\n");
}
if(file_exists($zip_file)){
$error .= $zip_file;
ob_end_clean();
// push to download the zip
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
header("Content-Length: " . filesize($zip_file));
readfile($zip_file);
unlink($zip_file);
}
}
}
}
echo $error;

After $zip->close(); I replaced all code for this:
if(file_exists($zip_file)){
header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-Length: ".filesize($zip_file));
header("Content-Disposition: attachment; filename=\"".basename($zip_file)."\"");
readfile($zip_file);
unlink($zip_file);
exit;
}

Related

How do I create zip file in PHP?

I want to create a zip file which contains some PDFs which are saved at my server.
Here is the code I tried,
$filenamez = 'datasheets1.zip';
$zip = new ZipArchive;
if ($zip->open('datasheets1.zip', ZipArchive::CREATE) === true) {
// Add files to the zip file
for ($m = 0; $m <= $total - 1; $m++) {
$zip->addFile('datasheet' . $m, $model1[$m] . ".pdf");
}
$zip->close();
echo 'Archive created!';
header('Content-type: application/zip');
header('Content-disposition: attachment; filename="' . $filenamez . '"');
header("Content-length: " . filesize($filenamez));
readfile($filenamez);
}
When I execute this code the zip file is created and downloaded but when I open it shows following error: " this archive is either in unknown format or damaged ".
In addition to Andrei's comment, you're echoing the string 'Archived Created!', and then also setting an application/zip header, and then streaming the contents of the ZIP file to the browser. So the content of the ZIP will be polluted by having that string inserted at the top, making it corrupt.

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

Debugging zip archive and download

I'd like a bit of help debugging this code. I'm trying to zip some files, which I provide as paths to Ziparchive. I think the zip file is empty, possibly. When I test this on a staging site I get a 'decompression failed' error. When I test this locally I get the following error in php logs
PHP Warning: readfile(images.zip): failed to open stream: No such file or directory in /Applications/MAMP/htdocs/8018_Whites/wordpress/downloadzip.php on line 29.
Here is the code:
<?php
//get image urls string
//$cat_string = "url1,url2,url3..."
if (isset($_GET['category-images'])) {
$cat_string=$_GET['category-images'];
}
//change string to array
$cat_array=explode(",", $cat_string);
$files=$cat_array;
$zipname = 'images.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
if(!strstr($file,'.php')) $zip->addFile($file);
}
$zip->close();
if ($zipname) {
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
exit();
}
?>
Do I need to add ob_start/ob_flush to this code, and should I put the ob_flush after readfile?
All files and Zip folder to give absolute path. so zip is properly created.
<?php
$zip_root ='/var/www/gplhome/'
$file_root ='/var/www/gplhome/project/'
//get image urls string
//$cat_string = "url1,url2,url3..."
if (isset($_GET['category-images'])) {
$cat_string=$_GET['category-images'];
}
//change string to array
$cat_array=explode(",", $cat_string);
$files=$cat_array;
$zipname = $zip_root.'images.zip';
$zip = new ZipArchive;
if ($zip->open($zipname, ZIPARCHIVE::CREATE) != TRUE) {
die("Could not open archive");
}
foreach ($files as $file) {
if(!strstr($file_root.$file,'.php')) $zip->addFile($file_root.$file);
}
$zip->close();
if ($zipname) {
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
exit();
}
?>
check the return value of $zip->close(), it returns false on error.
check the return value of $zip->addFile(), it returns false on error.
ensure that you use only file name for headers and full name for readfile.
check if the file is created. Replace
if ($zipname) {
with
if (is_readable($zipname)) {
don't put ?> and the end of the php file

Zip file is downloading with 20 bytes and when extracts the file it shows corrupted file and 'no archive found'

When i trying to download the zip file with the following code in my local system,the file is downloading with all the files but where as in server it is downloading with 20 bytes and when extracts file is corrupted and no archive found.So i added some checks for this code and run but this time File not found,going inside this check(if (!is_file($archive_file_name))).What might be the problem on server?
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_path as $file_path)
{
if(basename($file_path) =="documents")
{
foreach($file_names as $value=>$files)
{
$customer_files = $this->fetchCustomFieldValuesAndFieldNamesByOrder($files['order_id']);
if($customer_files['field_value'] !="" && file_exists($file_path.$customer_files['field_value']))
{
$file_extension = pathinfo($customer_files['field_value'], PATHINFO_EXTENSION);
$zip_file_name = $files['customer_name']."_"."Files.".$file_extension;
$zip->addFile($file_path.$customer_files['field_value'],$zip_file_name);
}
//echo $customer_files['field_value']."<br>";
}
} else
{
foreach($file_names as $value=>$files)
{
if($files['file_name'] !="" && file_exists($file_path.$files['file_name']))
{
$file_extension = pathinfo($files['file_name'], PATHINFO_EXTENSION);
$zip_file_name = $files['customer_name']."_"."Application".".$file_extension";
$zip->addFile($file_path.$files['file_name'],$zip_file_name);
// echo $file_path.$files['file_name'],$zip_file_name."<br>";
}
}
}
}
// echo "numfiles: " . $zip->numFiles . "\n";
// echo "status:" . $zip->status . "\n";
$zip->close();//exit;
//then send the headers to foce download the zip file
if (headers_sent()) {
echo 'HTTP header already sent';
} else {
if (!is_file($archive_file_name)) {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
echo 'File not found';
} else if (!is_readable($archive_file_name)) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
echo 'File not readable';
} else {
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=$archive_file_name");
header("Pragma: no-cache");
header("Expires: 0");
readfile("$archive_file_name");
exit;
}
}
}
If you're getting status 11 from $zip->status, it means that the file you're trying to ZIP does not exist. Here are docs on error codes from the Zip / ZipArchive class: http://php.net/manual/en/zip.constants.php
Verify that the path you're on is correct using getcwd() and that the file on this path really exists.

how to create rar/zipfile and download [duplicate]

This question already has answers here:
Dynamically creating zip with php
(2 answers)
Closed 9 years ago.
Hi frnds can anyone tel me how to Create a Zip File Using PHP?
Actually i am having 10 files with boxes,if i select more than one check box that files should get zip/rar and i am able to save that in some path..
Please can anyone help in this solution as i am new to php
$zip_name = 'path/to/final.zip'; //the real path of your final zip file on your system
$zip = new ZipArchive;
$zip->open($zip_name, ZIPARCHIVE::CREATE);
foreach($files as $file)
{
$zip->addFile($file);
}
$zip->close();
header('Content-type: application/zip');
header('Content-disposition: filename="' . $zip_name . '"');
header("Content-length: " . filesize($zip_name));
readfile($zip_name);
exit();
// This example creates a ZIP file archive test.zip and add the file /path/to/index.txt. as newname.txt.
$zip = new ZipArchive;
$res = $zip->open('test.zip', ZipArchive::CREATE);
if ($res === TRUE) {
$zip->addFile('/path/to/index.txt', 'newname.txt');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
//include your connection file
//$file_names[] get your files array
//$error = ""; //error holder
//$file_path='set your image path' folder to load files
if(extension_loaded('zip'))
{ // Checking ZIP extension is available
if(count($file_names) > 0)
{
// Checking files are selected
$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<br/>";
}
foreach($file_names as $file){
$zip->addFile($file_path.$file); // Adding files into zip
}
$zip->close();
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
{
$error .= "* Please select file to zip <br/>";
}
}
else
{
$error .= "* You dont have ZIP extension<br/>";
}
?>

Categories