Jump to content


Photo

Forcing save as dialog for image files not working


  • Please log in to reply
7 replies to this topic

#1 Chappers

Chappers
  • Members
  • PipPipPip
  • Advanced Member
  • 119 posts

Posted 10 October 2006 - 03:35 PM

Hi everyone,

I'm trying to force the browser to bring up a 'save as...' dialog box when a download link is clicked which is linked to a jpg image file, instead of opening the image in the browser.

After searching the net, I found the same snippet of code all over the place for doing this, but it won't work properly for me. Here's how the href link looks for a given image file:

<a href="image.php"><img src="images/save.gif" alt="save"></a>

So when the link is clicked, it references the image.php file, inside which is the following:

<?php
header('Content-disposition: attachment; filename=mypicture.jpg');
header('Content-type: image/jpeg');
readfile('images/mypicture.jpg');
?>

Now, I know that there can be no blank lines after the php code, or garbage may be added to the image file as it's rebuilt. The problem is that although this works and brings up a save as box, when you save the file, it's a 0Kb file.

It's the same behaviour as happens if you tell it to use a file that doesn't exist in the 'readfile' area. But I know the file is there and the address for the image file is correct and is how it's used on the rest of the site. I have the root directory on the server, with the "images" folder in the root, so image links are usually simply a href=images/whatever.jpg.

Can anyone help shed light on what's going wrong please?

#2 michaellunsford

michaellunsford
  • Members
  • PipPipPip
  • Advanced Member
  • 1,023 posts
  • LocationLouisiana, USA

Posted 10 October 2006 - 03:45 PM

There's a tutorial on this subject in the FAQ / Code Snippet Repository (in this forum). It uses very different headers, which may solve your problem:

http://www.phpfreaks...ic,95433.0.html

#3 Chappers

Chappers
  • Members
  • PipPipPip
  • Advanced Member
  • 119 posts

Posted 11 October 2006 - 10:14 PM

Thanks for the link. The code it gives is:
<?php
$file = $_REQUEST['file'];
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Content-Type: application/force-download");
header( "Content-Disposition: attachment; filename=".basename($file));
header( "Content-Description: File Transfer");
@readfile($file);
?>
Where the download link would be something like: a href=image.php?file=/images/example.jpg

It gives the same results as original code I posted though: downloaded file is 0Kb, as though it's not finding the jpeg image in the first place and so is making an image with the name I tell it to use, but which consists of no data. For the code above, I changed content-type to image/jpeg.

Any idea what I'm doing wrong?

#4 akitchin

akitchin
  • Staff Alumni
  • Advanced Member
  • 2,516 posts
  • LocationCalgary, AB, Canada

Posted 11 October 2006 - 10:21 PM

i would suggest trying to read the file without forcing a download to see if it's even finding the file.  otherwise instead of using readfile(), you could try using filesystem functions to see exactly where it's going wrong:

<?php

$handle = fopen($filename, 'r') or die('couldnt open file');
$contents = fread($handle, filesize($filename)) or die('couldnt read file');
fclose($handle);

echo $contents;

?>

these few lines would replace readfile().

#5 michaellunsford

michaellunsford
  • Members
  • PipPipPip
  • Advanced Member
  • 1,023 posts
  • LocationLouisiana, USA

Posted 11 October 2006 - 10:24 PM

Yeah, kill all the headers and see what readfile gives you all by it's lonesome.

#6 Chappers

Chappers
  • Members
  • PipPipPip
  • Advanced Member
  • 119 posts

Posted 12 October 2006 - 02:25 PM

Thanks again for the help, I appreciate it.

Tried removing headers so file read like:
<?php
$file = $_REQUEST['file'];
@readfile($file);
?>
But just get a blank page.

Not sure if that's exactly what you meant... sorry, still struggle with PHP.

Then did next suggestion of replacing @readfile with the code supplied, so it looked like:
<?php
$file = $_REQUEST['file'];
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Content-Type: application/force-download");
header( "Content-Disposition: attachment; filename=".basename($file));
header( "Content-Description: File Transfer");
$handle = fopen($file, 'r') or die('couldnt open file');
$contents = fread($handle, filesize($file)) or die('couldnt read file');
fclose($handle);
echo $contents;
?>

And it worked perfectly, the file downloaded and I opened the image to check it and it was fine.

So just curious, can I leave the code as above since it works? And, out of curiosity, why doesn't @readfile work, yet the code you gave me with which to replace readfile works perfectly?

Thanks for time and help.

#7 michaellunsford

michaellunsford
  • Members
  • PipPipPip
  • Advanced Member
  • 1,023 posts
  • LocationLouisiana, USA

Posted 12 October 2006 - 02:44 PM

Well, you're all fixed up, but now I'm curious about the readfile not working. That @ is supressing the error -- so if you want to know exactly what's happening you'd need to try it without the @. Post back.

#8 Chappers

Chappers
  • Members
  • PipPipPip
  • Advanced Member
  • 119 posts

Posted 13 October 2006 - 12:04 PM

Right, I did it this way, although not sure if it's the right way:
<?php
$file = $_REQUEST['file'];
$contents = readfile($file) or die('couldnt read file');
echo $contents;
?>
And it opened a new page stating 'couldnt read file'.

If I simply left the code alone and removed the headers and @:
<?php
$file = $_REQUEST['file'];
readfile($file);
?>
I just got a blank screen.

If this isn't what you meant, could you supply the code to try, please?




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users