PHP Zip 3 small text files and force download - php

My website writes 3 small text files based on users information and then presents these 3 files as links that they must "right click" and save to their desktop.
I would like to keep that, but also somehow offer a way to zip these 3 small files up and force download. And I don't want to save the zip file on the server either. Can this be done and how?
Thanks!

For the forced download you need to send out the file headers first.
header('content-type: application/zip');
header('content-disposition: inline; filename=YOUR_ZIP_FILE_NAME_HERE.ZIP"');
For zipping you'll wanna use one PHP's zip libraries, then echo/output the zipped content.
http://ca3.php.net/manual/en/zip.examples.php
Something like this:
$zip = new ZipArchive();
//the string "file1" is the name we're assigning the file in the archive
$zip->addFile(file_get_contents($filepath1), 'file1'); //file 1 that you want compressed
$zip->addFile(file_get_contents($filepath2), 'file2'); //file 2 that you want compressed
$zip->addFile(file_get_contents($filepath3), 'file3'); //file 3 that you want compressed
echo $zip->file(); //this sends the compressed archive to the output buffer instead of writing it to a file.

Related

using PHP to remove the extension from a file and then downloading it

I recently had a asked a question very similar to this one, however after evaluating that I did not explain it in the best way I have come back once again explaining it in a greater manner.
So, I am creating a system that will gather data from a MySQL database and use a unique id to download a file, however depending on the value of a column within that database called type, this file could be anything from a png file to an xml file. What I am currently doing is trying to download these files WITHOUT any extension.
As an example to maybe make this easier to understand, a file named image.png would be converted to just image and then downloaded.
With this you could rename the file to image.png again on the local machine and view the image.
This may seem very inefficient to most reading this but for my current situation it's all that will work.
How could I remove a files extension and then download it? (in php)
Thank you in advance.
Just use headers to specify response type.
$filepath = '/wherever/the/file/is.png';
$filename = 'new-cool-name';
header('Content-Type: whatever/content-type-is');
header("Content-disposition: attachment;filename=$filename");
readfile($filepath);
This basically sends a response with specified content-type as an attachment and the body of the attachment contains the file contents. If you never sure what's the content type is, then just use application/octet-stream
Usually when you set out to push a file for downloading from a serverside script, you do so by utilizing http headers like https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
The filename of the downloadable file is specified in that header
Okay so to remove an extention from a file you could do is
$withoutExtion = preg_replace('/\\.[^.\\s]{3,4}$/', '', $youfilename);
...followed by your file download code

How to debug/time my php function? Create Zip file

Have a php function to generate a zip file "on fly". I have the files on one server (AWS S3) but the PHP function to generate the zip-file is on another server/web hosting. I have noticed that it takes long time to generate the zip-file and I get a corrupt zip file if there are many files when I create zip file. I want to troubleshoot/debug where it takes "stop", what the missing link is if there are many files (the limit seems to be 20 files, which is not many).
How can I find out where in my function it fails if I have more than 20 files to generate my zip-file from?
Can I add a timer to every row?
Can I find out if it is memory or something else on my shared hosting (where I have the php function)? Or if it is something with S3.
My php function to generate the zip file from files on AWS S3
<?php
$imageQueryResult = $this->getUserImages('download', array('i.image_name'));
if(!empty($imageQueryResult)) {
$imageUrl = $this->getFromAmazon('download', $imageQueryResult);
$imageNumber = 1;
$zipName = 'tt-'.date("Y-m-d").'.zip';
//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($imageUrl as $image){
//Get extension
$ext = pathinfo(parse_url($image, PHP_URL_PATH), PATHINFO_EXTENSION);
//download file
$download_file = file_get_contents($image);
//add it to the zip
$zip->addFromString(basename($imageNumber.'-tt.'.$ext),$download_file);
$imageNumber++;
}
//close zip
$zip->close();
//send the file to the browser as a download
header('Content-disposition: attachment; filename='.$zipName);
header('Content-Length: ' . filesize($tmp_file));
header('Content-type: application/zip');
readfile($tmp_file);
ignore_user_abort(true);
unlink($tmp_file);
?>
You can try to use
http://php.net/manual/en/ziparchive.getstatusstring.php
ZipArchive::getStatusString — Returns the status error message, system and/or zip messages
You don't know how long it will take to compress all your files. So you'll have to check the maximal execution time and the memory that consumes that script.
If the problem is with the time, the solution might be to do this in chunks:
open the archive for writing
add N files per iteration
close the archive
Repeat until you you have files
Keep in mind that with this approach the more files you have, the more memory you need to store the temporary results

Link to a PDF in html, the file has no extension, but I know it is pdf how to make it open appropriately

First post. I'm working on a project for a client where they have pdf files uploaded to a file structure (LAMP Stack) but the files have no extensions on them. Under the assumption that those files have to be PDF how would I get the browsers to understand that, and open them accordingly? Obviously with adding the file extensions this would suddenly work but I can't change the way their system works, it would result in too many changes and they are on a tight deadline. As for saving a temporary copy somewhere, I could do that, but I was hoping for a better solution. Is there a way to suggest to the browsers that they open a file a certain way?
Any thoughts guys/gals?
You just set the application type and file name in the headers, like so:
// This points to the file in question, note that it doesn't
// care whether it has an extension on the name or not.
$filePathOnDisk = '/path/to/your/pdffile';
// You can make this whatever you like, it doesn't have to
// be the same as the file name on the disk! This is the name of the file your end
// user will see when they are asked if they want to save. open, etc in the browser.
$fileName = 'file.pdf';
$data = file_get_contents($filePathOnDisk);
header("Content-type: application/pdf");
header("Content-disposition: attachment;filename=$fileName");
echo $data;
See PHP: stream remote pdf to client browser and Proper MIME media type for PDF files for reference as well.
Tested
You can use the following which will prompt the user to save the (PDF) file on their computer.
Notice the different file names.
One is the file that will be uploaded/prompted to the user download_example.pdf, while the other is the file without an extension as set in readfile('example');
<?php
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="download_example.pdf"');
readfile('example');
?>

Renaming file while downloading from other website

I am trying to rename file and download it for user!
Example... In my website I offer to download Google Logo from my website link!
http://www.mywebsite.com/files/logo-mysite.jpg
then the file is saved as logo-mysite.jpg in the users computer but the file in real is downloaded from https://www.google.co.in/images/srpr/logo4w.png
We can do it by saving the image from https://www.google.co.in/images/srpr/logo4w.png temporary to our website and then auto-delete it on download or auto-delete within 1 hour!
You can suggest a filename for a download by adding a content-disposition header:
header('Content-disposition', 'attachment;filename=logo-mysite.jpg');
die(file_get_contents('https://www.google.co.in/images/srpr/logo4w.png'));
Obviously this would give problems since you are downloading a png file with a jpg extension, but I'm just following your question... To convert the image you'd need to add some lines of GD2 code.
Use the header() function to set the name that the user will download:
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename=logo-mysite.png');
// Open the new file, and dump it out to the user
$handle = fopen( "https://www.google.co.in/images/srpr/logo4w.png" );
fpassthru( $handle );
fclose( $handle );
If you really want to convert it from jpg to png, you'll need to run it through ImageMagick or the likes.

dompdf Customization Question

I'm trying to optimize dompdf to do something a bit strange. As it is on my server, dompdf is generating a pdf file (for the client requesting the file) from a php/html file stored somewhere on the server. This is cool because it doesn't bog the server down with pdf files, but the problem I have is that I want someone to be able to export a group of PDFs and receive them in a zip file or something similar.
Is there a way to make dompdf export a group of PDF files, based on the filenames of the php/html files, to a zip file or something so the person requesting it can download it?
Let me know if more information is needed.
Thank you!!
DOMPDF only handles a single file at a time. But you could write a PHP script to accept the list of files and then use DOMPDF to parse each one separately. Since DOMPDF can return the rendered PDF as a string you could write each file out to a temporary directory then archive the results when you're done. Or, if you're using dompdf.php you could use exec() to process each HTML document in a similar loop.
Here's a simple example showing one way to do what you want:
$files_html = array('docs/file1.html','docs/file2.html');
foreach ($files_html as $file) {
exec('dompdf.php ' . $file);
}
$zip = new ZipArchive();
$zip->open('docs/pdfs.zip', ZipArchive::CREATE);
$files_pdf = glob('docs/*.pdf');
foreach ($files_pdf as $file) {
$zip->addFile($file);
}
$zip->close();
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=pdfs.zip);
header('Content-Transfer-Encoding: binary');
readfile('docs/pdfs.zip');
There are some discussions of using DOMPDF to batch process files in the forum and issue tracker.

Categories