Create PDF with DOMPDF and Redirect - php

In a PHP project I need to Create a PDF file and redirect to another page when user clicks a Submit button.
I have managed to create the pdf file using DOMPDF. PDF creation is done in a seperate file ('PDFRecipt.php').
I have called that page when a user clicks a button on the main page. This is how call PDF page
header('location:PDFRecipt.php');
but the problem is when I try to redirect after calling PDF page by
header('location:Other.php');
It does not create the PDF (only redirects). I tried changing
header('location:PDFRecipt.php');
to
include_once('PDFRecipt.php');
then it does not create the PDF correctly (Corrupted PDF File)
How to create the PDF file & redirect to other page?
EDIT:
Code in PDFRecipt.php
$html='SOME HTML';
include("../../dompdf/dompdf_config.inc.php");
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream('FileName.pdf');
//header('location:Other.php);

Answer to question
For this to work you would need to move the second header call into the PDFRecipt file. At the moment with both of them in the one file your second call to header is overriding the first.
Remember that headers are sent when the output is sent to the users browser, which is why you often see people calling exit() right after a header('Location: http://example.org');.
So any subsequent calls to set the same header, in this case Location, will override the first until the headers are sent.
It is also worth pointing out that you should be using full web URLs in Location:
HTTP/1.1 requires an absolute URI as argument to ยป Location: including
the scheme, hostname and absolute path, but some clients accept
relative URIs. You can usually use $_SERVER['HTTP_HOST'],
$_SERVER['PHP_SELF'] and dirname() to make an absolute URI from a
relative one yourself
according to the header page in the manual: http://php.net/manual/en/function.header.php
Update from comments
So you are using the stream() method to send the client the PDF - you cannot combine this with a Location: header. This is because DOMPDF has already flushed content to screen. I had assumed that your PDFRecipt.php file was storing the PDF to disk somewhere.
See DOMPDF source code for more details: http://code.google.com/p/dompdf/source/browse/trunk/dompdf/lib/class.pdf.php#3061

Related

Force download of PDF file on the same PHP page

I have a PHP file that includes a link to a .pdf file that opens in a new tab - this essentially simply opens the page which downloads the PDF to the user's downloads folder immediately - the new tab doesn't remain open in the browser. This is all working well.
I'm now trying to change it so that the php page will load and do the download of the pdf in the one page, without the user having to click another link to download the pdf file.
Here's the structure with the 2 page setup - the viewReport.php page has a link like this:
$downloadLink = 'downloadFile.php?fileName='.$fileName.'&path='.$url;
$displayLink = 'This Report was successfully created. Click here to view the PDF.';
The downloadFile.php page has the following:
$fileName = $_GET['fileName'];
header('Content-type: application/force-download');
header('Content-Disposition:filename="'.$fileName.'"');
echo $fm->getContainerData($_GET['path']);
which works to immediately download the PDF. I've now changed the viewReport.php page to include this:
$downloadLink = 'downloadFile.php?fileName='.$fileName.'&path='.$url;
header('Content-type: application/force-download');
header('Content-Disposition:filename="'.$fileName.'"');
echo $fm->getContainerData($url);
When this page loads it does download a PDF file that it cannot be opened and is about 1/3 the size of the one that is generated with the 2 page version, so obviously not a valid PDF file. Also the viewReport.php page appears to stop loading once it processes this line hat downloads the pdf file:
echo $fm->getContainerData($url);
and then appears to go back to the previous page.
This is my first time trying to do this in a single page so not sure if this can even be done this way?
You won't be able to do both actions of rendering a new page for the user to view while simultaneously triggering an automatic file download with a single request.
The problem is that both of those actions require specific headers being sent in order to deliver their payloads correclty. Obviously you're seeing the headers you need to set to trigger the file download, but the delivery of a web page also requires specific headers which are normally set for you in the background. And the headers for delivering a web page for viewing vs. a file download are not compatible with each other - you can only send one or the other in a single response.
With all that said, there are probably other workarounds possible using javascript and ajax. But ultimately it all comes down to sending separate requests in order to receive two distinct sets of headers required for the two scenarios.

Filename incorrect in save dialog - Firefox

I am redirecting to an image with a Location header from PHP, and in firefox when you view the image and right click to save it prompts to save with the name of the PHP redirect script, not the name of the image. This behaviour is not present in the other browsers.
Here is the code of the file:
<?php
header("Location: foo.jpg");
Is there anyway to get firefox to use the correct name when a user opens the save dialog?
jewlhuq's suggestion to bypass php altogether works.
<?php print("<script>window.location='image.jpg';</script>"); ?>
Using php to read the file's contents and dump those to the browser with the proper headers including the following
header('Content-Disposition: inline; filename="desired-filename.jpg"');
also works.
Which is better depends on your application. I used the first for the problem listed above, in another application I needed to serve an image with a different file name than the one it is actually saved with, for that I needed the latter.

Page Not Redirecting to controller after generating a pdf file

I am using Codeigniter as a PHP framework and DOM PDF to generate pdf files. I have the following codes in my Controller.
// Some other codes
include_once('dompdf/dompdf_config.inc.php');
$dompdf = new DOMPDF();
$base_path = $_SERVER['DOCUMENT_ROOT'];
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream("invoice_$studentid.pdf");
redirect("my_Controller");
The problem is after generating the pdf file it is not redirecting to the Controller. Could you please tell me how to solve this problem?
$dompdf->stream is sending the PDF to the browser. You can't also send a redirect header. You're trying to output two responses to one request, which is impossible.
This doesn't seem like it should be a problem. The browser will stay on whichever page the user was on when they clicked the link to download the PDF. If you really want them to be forced elsewhere (you probably don't, that's a very different user experience from how download links work everywhere else) you could do something with JavaScript.

Clean up after creating the pdf

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()

How do I load an image in PHP

I want code that loads an image to a PHP server and then send it to browser.
For example I want sample.php to send an image to browser once it is requested.
in other words, I want to create a PHP file that acts like a proxy for an image.
why are you doing this?
why don't deliver the image directly?
if you are trying to display a random image you may as well just redirect to the image using
header("Location: address-of-image");
for delivering the file to your clients from your server and not from its original location you can just do. however your php.ini settings need to allow external file opens
readfile("http://www.example.com/image.jpg")
correct headers are not required if you are going to display the image in an img tag,
altough i would recommend it. you should check the filetype of the image or in most cases just set an octet-stream header so the browser doesnt assume an incorrect type like text or something and tries to display binary data.
to do so just do
header("Content-type: application/octet-stream")
one more thing to consider may be setting correct headers for caching...
You need to use
$image = fopen("image.png");
Modify the headers(not sure exacly if it's correct)
headers("Content-type: image/png");
And then send the image
echo fread($image, file_size("image.png"));

Categories