I'm generating a pdf file with html2fpdf.
$pdf = new HTML2FPDF();
$pdf->HTML2FPDF("P","mm","A4");
$pdf->AddPage();
$pdf->WriteHTML($html);
$pdf->output('sample.pdf');
This sample works great. But:
How do I delete the pdf after the output? I just want to have links in my tool, the users can download the pdf and after that it shoud be deleted on the server.
How can I 'clean up' after generating the pdf?
You can use PHP's file deletion function called unlink()
Call this function with the full path to the generated PDF file (or any file for that matter) and PHP will delete that file.
http://php.net/manual/en/function.unlink.php
You don't necessarily have to delete the file immediately after the user has downloaded it. You can just as easily place all the generated files in one central folder and have a cron job execute a more general clean up script simply removing the older files.
One method could be -
Scan the contents of the folder using scandir().
Iterate over its files in a foreach loop..
Inspect the creation time of each file using filemtime().
If the creation time was over hour ago, delete the file using unlink().
Because you are generating the PDF file yourself within your PHP code, I didn't mention the permissions consideration. Here would be a good place to mention that your PHP must have the correct file system permissions in order to perform any action on the file system. You are creating a PDF file so it's safe to assume that you have the correct permissions to make changes to the file system but if you plan on using this unlink() function in other scripts make sure that the files you are dealing with have the correct permissions set.
If you don't add the 'F' flag to the output function there will be no pdf files stored on the server at all:
$pdf->output('sample.pdf', 'F'); //stores PDF on server
In your case the script itself behaves like an actual pdf file. So, creating a link to the script is just like a link to the pdf, except that the PDF is created every time the script is requested. To tell the browser it's a PDF the content-type response header must be set to application/pdf:
content-type: application/pdf
This way the broser knows that it's a pdf even if the URL is ending in a .php. You can use rewrite engine to make it end in pdf or whatever else.
Sending the headers is done by the fpdf/tcpdf. In short: you don't have to do any cleanup, because no pdf file is stored on the server.
If you wonder what the name is for than, try saving the pdf file. The recommanded name when saving will be sample.pdf.
Reference:
PHP header() function, at the examples there is one for sending pdf
FPDF::Output()
TCPDF::Output()
Related
I have a PHP application that generates a CSV file and redirect the user to a static page linking to the file, just the example below :
https://www.example.com/public_html/static/temp/myfile.csv
Problem is, Chrome is opening the file instead of saving it. I need Chrome to save this file, as it would do with any other file like a zip or mp3, for instance.
Here is what I tried :
header('location:https://www.example.com/public_html/static/temp/myfile.csv');
header('Content-Disposition: attachment; filename=myfile.csv');
But no luck, Chrome keeps showing the myfile.csv contents instead of downloading it.
Any ideas ?
Thanks
Your argumentation in the comments has one never-ending misunderstanding: the Location header instructs any client to perform a new request to the given URI. With that the current request is over. Headers from the current request (i.e. Content-Disposition) aren't magically carried over to the next request.
In other words: your "static page linking to the file, just the example below" must send your wanted header.
Ultimately I'm sure it's not a Chrome problem either, but affects all internet browsers, as they easily detect the CSV data as text, hence being able to render/display that data instead of only being able to save it to a file.
With html5 you can set the "download" attr in an element.
Download it!
Source : http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download
After struggling with this issue for some days, the only real solution i got is to ZIP the file and then redirecting to the ZIP file instead of the CSV. By doing this, Chrome will download the ZIP file instead of opening it :
header('location:https://www.example.com/public_html/static/temp/myfile.csv.zip');
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
I am trying to generate an archive on-the-fly in PHP and send it to the user immediately (without saving it). I figured that there would be no need to create a file on disk as the data I'm sending isn't persistent anyway, however, upon searching the web, I couldn't find out how. I also don't care about the file format.
So, the question is:
Is it possible to create and manipulate a file archive in memory within a php script without creating a tempfile along the way?
I had the same problem but finally found a somewhat obscure solution and decided to share it here.
I came accross the great zip.lib.php/unzip.lib.php scripts which come with phpmyadmin and are located in the "libraries" directory.
Using zip.lib.php worked as a charm for me:
require_once(LIBS_DIR . 'zip.lib.php');
...
//create the zip
$zip = new zipfile();
//add files to the zip, passing file contents, not actual files
$zip->addFile($file_content, $file_name);
...
//prepare the proper content type
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=my_archive.zip");
header("Content-Description: Files of an applicant");
//get the zip content and send it back to the browser
echo $zip->file();
This script allows downloading of a zip, without the need of having the files as real files or saving the zip itself as a file.
It is a shame that this functionality is not part of a more generic PHP library.
Here is a link to the zip.lib.php file from the phpmyadmin source:
https://github.com/phpmyadmin/phpmyadmin/blob/RELEASE_4_5_5_1/libraries/zip.lib.php
UPDATE:
Make sure you remove the following check from the beginning of zip.lib.php as otherwise the script just terminates:
if (! defined('PHPMYADMIN')) {
exit;
}
UPDATE:
This code is available on the CodeIgniter project as well:
https://github.com/patricksavalle/CodeIgniter/blob/439ac3a87a448ae6c2cbae0890c9f672efcae32d/system/helpers/zip_helper.php
what are you using to generate the archive? You might be able to use the stream php://temp or php://memory to read and write to/from the archive.
See http://php.net/manual/en/wrappers.php.php
Regarding your comment that php://temp works for you except when you close it, try keeping it open, flushing the output, then rewind it back to 0 and read it.
Look here for more examples: http://us.php.net/manual/en/function.tmpfile.php
Also research output buffering and capturing: http://us.php.net/manual/en/function.ob-start.php
You need to use ZipArchive::addFromString - if you use addFile() the file is not actually added until you go to close it. (Horrible bug IMHO, what if you are trying to move files into a zip and you delete them before you close the zip...)
The addFromString() method adds it to the archive immediately.
Is there really a performance issue here, or does it just offend your sense of rightness? A lot of processes write temporary files and delete them, and often they never hit the disk due to caching.
A tempfile is automatically deleted when closed. That's it's nature.
There are only two ways I can think of to create a zip file in memory and serve it and both are probably more trouble than they are worth.
use a ram disk.
modify the ziparchive class to add a method that does everything the close() method does, except actually close the file. (Or add a leave-open parameter to close()).
This might not even be possible depending on the underlying C libraries.
I want to force download a pdf,doc or docx file.
With the following code,Pdf files get opened in my tab instead of getting downloaded.
I have a table having download link in every row.I want to download file on click of this link.
foreach($a as $id = > $item) {
echo '<tr><td><a href="http://staging.experiencecommerce.com/ecsite-v3/uploads/'.substr($item['f_resume'], 63).'" ">';
//Note:substr($item['f_resume'], 63) is file_name
echo '</a></td><td>'.$item['f_date'].'</td></tr>';
}
I went through some Question on SO with same problem and tried their solution,but in Vain.
When I included the solution inside foreach,the page downloads file on load and when I place the solution outside ,the Php script gets downloaded.
Where am I going wrong?
You can set headers that will force downloading:
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="filenamehere.pdf"');
If you're not using PHP to provide content of that files you can set headers using eg. .htaccess (requires mod_headers).
<FilesMatch ".pdf$">
FileETag None
<ifModule mod_headers.c>
Header set Content-Type "application/force-download"
</ifModule>
</FilesMatch>
After our whole chat session I think we can leave this answer here, just for future reference:
As seen in your initial post, once you click the link, you relinquish all control to the browser so it will treat the file as it sees fit. Usually this involves trying to find whatever application or plugin the system can find to treat your file.
Whenever you want to force the download of the file all you have to do is divorce the presentation itself from the task at hand. In this particular case:
1 - Create a new script that will identify the file via parameters passed and force the download on it, as seen on the examples at this site php.net/manual/en/function.readfile.php.
2 - Rework the presentation so the links do no longer point to the file itself, but to the new script with the appropriate parameters (like, for example, download_file.php?file_id=#FILE_ID#).
3 - Treat the case in which the file can not be found by, for example, die("The file could not be found") before setting the headers.
One word of advice: do not use the file location as a parameter!!!. Use instead something that you can retrieve from a database to then collect the file location. If you pass the file location itself as a parameter nothing is stopping me from doing this:
http://yoursite.com/download_file.php?file=download_file.php
http://yoursite.com/download_file.php?file=index.php
http://yoursite.com/download_file.php?file=whatever_file_there_is
With the adequate circumstances, like autodetection of the xtype for the requested file, it would allow me to access your code and exploit any possible flaws
One second and final note of advice: php can only output one thing at once. If you want it to output a website you can't output a pdf file afterwards. That's why - among other reasons - you divorce the different tasks at hand and also, that's why everything went awry when you tried directly including the download script after each link was printed.
If it helps, imagine php not as your usual real-time programming language, but as a printer. It will print everything you tell it to and serve it in reasonably sized chunks. There's no stopping it until the end is reached, there's no possible exploring two opposite branching code paths unless you call the script again with the appropriate conditions.
Hope the chat helped you.
I have a script which uploads files into an online directory and stores the file details in a database. The files when stored are renamed to the id of the entry in the database. Whenever a user requests a download, a simple SQL statement retrieves the file details from the database, the contents of the file are read from the database, and the file is prompted for download. The following is my code:
$one_file = $FILE_OBJECT->get($_GET['id']); // this is an object which just grabs the file details from the database
header("Content-type: ".$one_file['type']); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\"".$one_file["filename"]."\""); // use 'attachment' to force a download
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$one_file["filename"]."\"");
readfile(_config('files_path').$_GET['id']);// reading the actual raw file stored in my online directory
Problem is that Im testing using a word document and its uploading perfectly - I've even checked the raw file being uploaded by manually changing its extension and it's uploading perfectly. The problem is that when it's downloaded using the code above, the Word file seems corrupted or something, because when I try to open it, it's all mumbled and jumbled. What's happening? I've used this snippet on a few other sites I've worked on, and they work perfectly fine... Help please!
By default PHP's header function will replace previous headers with the same name, so your first two headers are being overwritten by the second two. Delete the second two and see if that works.
See if this helps:
Webkit and Excel file(PHPexcel)
I was having the same problem: every time I downloaded a file, it was supposedly "corrupt". Turns out I had made a stupid directory path mistake, but the php error was being written into the downloaded file. Which, of course, made it "corrupt".
Actually I solved by reading Ian Wetherbee's comment about testing with a plain text file. Thanks Ian!