PHP ZipArchive - Downloaded file says i'ts empty but it's not - php

I have the below code that creates a ZIP file, adds a file to it and then downloads to my computer.
$zip = new ZipArchive();
if ($zip->open('order_sheets.zip', ZipArchive::CREATE) === TRUE){
$zip->addFile($pdfFilePath);
}
$zip->close();
$file_url = 'order_sheets.zip';
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$file_url);
header('Content-Length: ' . filesize($file_url));
readfile($file_url);
All works good but the issue is, when opening the downloaded ZIP, it say's This folder is empty when it is not. If i right click and hit "Extract Here", the contents come out.
Anyone know why that is?

The problem is with Windows' zip utility, which uses IBM850 encoding causing it to misinterpret some characters in internal filenames in the archive, including _ (underscore) as in your file.
See answer here:
PHP ZipArchive Corrupt in Windows
Explained in PHP Manual user notes here: http://php.net/manual/en/ziparchive.addfile.php#95725

Related

ZipArchive invalid in Windows only

I am using ZipArchive with the following code to create zip files. It works well in all browsers on a Mac. But it says the file is invalid on any browser on a Windows computer. I don't understand why. I emailed the supposedly corrupt file from the Windows computer to myself and opened it on my Mac computer, and it worked fine. I also read through all the suggestions on this thread and tried all of them, with no luck.
Do you see anything wrong with my code?
if(extension_loaded('zip')){
if(isset($post['afiles']) and count($post['afiles']) > 0){
$zip = new ZipArchive();
$url = get_stylesheet_directory();
$filepath = $url;
$zip_name = "DSV".time().".zip";
if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE){
$error .= "Error";
}
foreach($post['afiles'] as $file){
// get the file directory url from the file ID
$path = get_attached_file( $file );
// add each file to the zip file
$zip->addFile($path, basename($path));
}
$zip->close();
ob_clean();
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
readfile($zip_name);
unlink($zip_name);
}else
$error .= "* Please select file to zip <br/><br />";
}else
$error .= "* You do not have the ZIP extension<br/><br />";
I echoed basename($path) to confirm that there are no slashes. It is simply the filename like "this-is-my-file.docx". Thanks for any insight!
Edit: The exact error in Windows says:
Compressed (zipped) Folders Error
Windows cannot open the folder.
The Compressed (zipped) Folder 'C:\Users\krist\Downloads\DWV1620652983.zip' is invalid.
After inspecting the ZIP files, there's HTML coming after the ZIP content. The fix is to make sure to call exit as soon as possible after calling readfile so that nothing else is written to the stream.

Archive format is not recognised. ZipArchive in PHP not returning a valid format

Thanks in advance for your help
This is happening in a Ubuntu 20.10 machine and a server with apache and php 5.2
Let me paste the code:
$elementsToDownload = array(
'productTableCSV' => $productTableCSVString,
'productTableLangCSV' => $productTableLangCSVString,
'productTableShopCSV' => $productTableShopCSVString
);
// var_dump($elementsToDownload);
$zipname = 'productCSVs.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($elementsToDownload as $key => $csvString) {
if (! $zip->addFromString("$key.csv", $csvString)) {
echo 'Could not add file to ZIP: ' . "$key.csv";
die();
}
}
$zip->close();
ob_clean();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
unlink($zipname);
It looks like something should be wrong in here, as I, randomly, can download the zip. From time to time the browser complains about not being able to download the file. Although this is not always happening, this is the message that Firefox display:
/tmp/mozilla_manu0/h03iaHVG.zip.part could not be saved, because the source file could not be read.
Try again later, or contact the server administrator.
This happens in Firefox.
Nor Mate Engrampa Archive Manager neither XArhiver are capable of opening the file. Surprisingly if I run unzip -t productCSVs.zip in the command line, it doesn't report any error. I can also unzip the file without the -t option if I do in the terminal, but no desktop app can open it.
To add some extra information, the PHP version which I'm using to generate the file is quite old, 5.2, but this is what I have until my company updates their systems, which is expected in the future.
Can anybody think of any reason why this could be happening?
EDIT:
I just realised that even though I don't have errors when decompressing the file in the terminal, I have a warning about 1 extra byte at the beginning or within zipfile:
manu#manu-NUC8i7BEH:/tmp/mozilla_manu0$ unzip -t productCSVs.zip
Archive: productCSVs.zip
warning [productCSVs.zip]: 1 extra byte at beginning or within zipfile
(attempting to process anyway)
testing: productTableCSVString.csv OK
testing: productTableLangCSVString.csv OK
testing: productTableShopCSVString.csv OK
testing: productTableCSV.csv OK
testing: productTableLangCSV.csv OK
testing: productTableShopCSV.csv OK
No errors detected in compressed data of productCSVs.zip.
I still can't understand what's going on in here
Ok, so I solved the issue.
My problem was that I had opened and closed two times the php tags in my code, leaving a space in between. Something like this:
?>
<?php
As a result that space was being added to the download stream.
I removed the closing tag and the opening tag, as they were together, and now every file I download from the server is recognised by all my zip tools
Thank you for having read me!

Download APK file using PHP

I am trying to download an android APK file using php in my PC browser using Chrome.
My app is located in a particular path in the server. If I manually FTP the file from server and transfer to my android mobile it installed perfect. But when I downloaded using PHP and transfer the downloaded file to Mobile and while installing it throws 'there was a problem while parsing the package'.
Here is my PHP code I use to download
header('Content-Type: application/vnd.android.package-archive');
header('Content-Disposition: attachment; filename="' . $file_name . '"');
readfile($file_path);
return true;
fyi...
$file_name is the apk file file 'myfile.apk'
$file_path is the full absolute path of the file in server ('d:\abcd\xyz\xampp\htdocs\apkstore\myfile.apk')
I found one observation while trying to open the APK file using 7-zip.
When I open the file using 7-zip it throws an error 'Cannot open the file xxx as archive'
After I added the below PHP code
header("Content-length: " . filesize($file_path));
Now when I open the file using 7-zip it opens the file but the size of the downloaded file is greater than the original file. And when I open this file in mobile the same error 'there was a problem while parsing the package'
To cut my long story short, I am trying to download an APK file from server to localhost using PHP and I'm able to make it work.
I managed to make it work by adding ob_end_flush()
header('Content-Type: application/vnd.android.package-archive');
header("Content-length: " . filesize($file_path));
header('Content-Disposition: attachment; filename="' . $file_name . '"');
ob_end_flush();
readfile($file_path);
return true;

Force docx file download via PHP corrupt

I know there are a lot of mentions of this but I have tried all the suggestions and nothing seems to work.
I have this script to force download files, but when using docx formats it downloads ok but then says the file is corrupt. However word does manage to open it ok.
Does anyone know why the docx would keep saying there corrupt. I have double checked them by ftp them down from the server and they are fine and open first time.
$documentDir = '/home/';
$file = $_GET['d'];
$fileLocation = $documentDir.$file;
header('Content-type: application/octet-stream');
header('Content-Length: ' . filesize($fileLocation));
header('Content-disposition: attachment; filename="'.$file.'"');
readfile($fileLocation);
exit(0);
This script works for me.
Are you sure that all your documents are situated in /home/ ?
Don't you mean the relative path home/
If this still doesn't work, can you please tell what's the size of the downloaded docx, and open that file in a text editor like sublime_text, the error will probably be written in there.
You could try modifying disposition line and adding encoding line to ensure encoding is done correctly.
header ("Content-Disposition: attachment; filename*=UTF-8'en'$file");
header('Content-Transfer-Encoding: binary');

Using JavaScript and PHP to download image files and return a zip file

I'm in the middle of developing a Safari extension for imageboard-type websites and one of the bigger features I'm hoping to implement is the ability to download all of the images (the posted ones, not the global page-level images) that had been posted.
There are similar questions here already, but mine differs a bit in that the images in question are hosted on an entirely different server. I've been brainstorming a bit and figured that gathering all of the image URLs in a JS array then sending it to my server to be turned into a zip file (forcing the download, not just a link to the file) would be the best way to go. I also want the zip to be deleted after the user downloads it.
I've already finished the majority of the extension features but this one is stumping me. Any help would be greatly appreciated.
How would I'd go about doing this?
You want a extension to contact your server for downloads? That's a terrible idea! Make the zipfile locally - it's not regular javascript, it's an extension - you have full access.
Anyway assuming you want to do this anyway, what is the trouble you are having? You get a list of urls, send them to your server, your server downloads them, zips them and send them to the user. (The "your server downloads them" part should worry you!)
What problem are you having?
You can use PHP's ZipArchive class to make a ZIP, then stream it to the browser.
<?php
// Create temp zip file
$zip = new ZipArchive;
$temp = tempnam(sys_get_temp_dir(), 'zip');
$zip->open($temp);
// Add files
$zip->addFromString('file.jpg', file_get_contents('http://path/to/file.jpg'));
$zip->addFile('/this/is/my/file.txt');
// Write temp file
$zip->close();
// Stream file to browser
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=myFile.zip');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($temp));
readfile($temp);
unlink($temp);
exit;

Categories