0

I have a form that submits to a php script which I would like to do the following:

  1. capture the user input via POST (done)
  2. send me an email with the user's details (done)
  3. start downloading a PDF from the same directory as the .php file (test.pdf) - HELP!

EDIT: FYI, I am calling the php via jquery:

$.ajax({
    type: "POST",
    url: php_url,
    data: $('#popForm').serialize(),
            success: function(){
           window.location.href = 'downloadpdf.php?file=test.pdf';
        }
    })

Here is the php code that captures the user input via POST and sends it to me via email. I just need a section that does #3, above.

<?php

$email_PGi = "me@mail.com";
$email_subject = "some email subject";


$firstname = $_POST['firstname']; 
$lastname = $_POST['lastname']; 

$email_message = "The following is a new message received via the website:\n\n";

function clean_string($string) {
  $bad = array("content-type","bcc:","to:","cc:","href");
  return str_replace($bad,"",$string);
}

$email_message .= "First Name: ".clean_string($firstname)."\n";
$email_message .= "Last Name: ".clean_string($lastname)."\n";


// create email headers
$headers = 'From: '.$biz_email."\r\n".
'Reply-To: '.$biz_email."\r\n" .
'X-Mailer: PHP/' . phpversion();

@mail($email_PGi, $email_subject, $email_message, $headers);


?>

downloadpdf.php

<?php

$file = $_GET['file'];
header('Content-Type: Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Length: ' . $file);
readfile($filename);
die();

?>
p1xelarchitect
  • 289
  • 1
  • 6
  • 19

4 Answers4

1

It's because the response (with correct headers) is being received by the ajax request, which isn't going to output to the user. You can try one of three things:

  1. Don't use ajax for this.
  2. Use File API and have the ajax callback handle the file data (major pain).
  3. Have the ajax callback set the window.location value to a script that only uses the Content-Disposition: attachment header so that the browser starts to "redirect" but instead downloads the file as indicated by the header.

Also, possible duplicate of Download a file by jQuery.Ajax

Community
  • 1
  • 1
Anthony
  • 36,459
  • 25
  • 97
  • 163
0

Use http://php.net/manual/en/function.file-get-contents.php to send the data along with your headers, not readfile.

kwolfe
  • 1,663
  • 3
  • 17
  • 27
  • I'm sorry kwolfe, while this may be the answer, none of the examples on the link you shared pertain to what I'm trying to do (download a PDF file). Can you show me how you would use this in my php script above? – p1xelarchitect Aug 01 '13 at 13:29
0

Use:

define('PDF_FILE', 'test.pdf');

header('Content-Type: application/pdf');
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=" . basename(PDF_FILE));
header('Expires: 0');
header('Content-Length: ' . filesize(PDF_FILE));

ob_clean();
flush();

readfile(PDF_FILE);
haim770
  • 48,394
  • 7
  • 105
  • 133
  • I tried this exact code and it did not work. when i hit the submit button, my jquery code (validation) works fine, and I DO receive the email from the php script, but no file download.. Does it help to know I'm calling the php script via jquery $.ajax()? – p1xelarchitect Aug 01 '13 at 13:37
  • @p1xelarchitect That usually doesn't work I believe. I do think you should've put that in your question though. – MisterBla Aug 01 '13 at 13:39
  • Yes, `jQuery.ajax` couldn't trigger the file-download dialog in the browser. check this: http://updates.html5rocks.com/2011/08/Saving-generated-files-on-the-client-side – haim770 Aug 01 '13 at 13:46
0

Have you tried opening a window that forces the download? This is probably not the best nor cleanest solution, but it'll work.

JQuery:

$.ajax({
    type: "POST",
    url: php_url,
    data: $('#popForm').serialize(),
    success: function()
    {
       window.location.href = 'downloadpdf.php?file=test.pdf';
    }
});

downloadpdf.php?file=test.pdf

$file = $_GET['file'];
header('Content-Type: Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Length: ' . $file);
readfile($filename);
die();

I'm not sure if you plan on passing the filename to the callback later on.

MisterBla
  • 2,355
  • 1
  • 18
  • 29
  • forgive me, I'm new to php... this is probably a silly question, but what is the actual name of the php file in your example? "downloadpdf.php" ? – p1xelarchitect Aug 01 '13 at 13:56
  • The name of the file is indeed _downloadpdf.php_ and I'm passing the file name through a `$_GET` variable. Please note that this example assumes that your pdf is in the same folder as downloadpdf.php. – MisterBla Aug 01 '13 at 13:58
  • OK! Closer... I tested it in Safari - no dice - nothing happens. Tested in IE9, IE10 and FF - it works, but gets caught in the pop up blocker. Any way around that? – p1xelarchitect Aug 01 '13 at 14:15
  • I edited my answer. Try using `window.location.href = 'downloadpdf.php?file=test.pdf';` instead. – MisterBla Aug 01 '13 at 14:18
  • hmm. yes, that solved the problem in IE - but now it's jamming all the other browsers. It's calling mydomain.com/downloadpdf.php?file=test.pdf perfectly, but the loading icon just spins forever. a problem with the php? – p1xelarchitect Aug 01 '13 at 14:30
  • If it works in IE and nowhere else it shouldn't be a PHP thing. Maybe remove the `die();` statement. – MisterBla Aug 01 '13 at 14:52