Jump to content

Archived

This topic is now archived and is closed to further replies.

Chappers

Forcing save as dialog for image files not working

Recommended Posts

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:

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

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

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

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?

Share this post


Link to post
Share on other sites
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.com/forums/index.php/topic,95433.0.html

Share this post


Link to post
Share on other sites
Thanks for the link. The code it gives is:
[code]<?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);
?>[/code]
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?

Share this post


Link to post
Share on other sites
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:

[code]<?php

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

echo $contents;

?>[/code]

these few lines would replace readfile().

Share this post


Link to post
Share on other sites
Thanks again for the help, I appreciate it.

Tried removing headers so file read like:
[code]<?php
$file = $_REQUEST['file'];
@readfile($file);
?>[/code]
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:
[code]<?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;
?>[/code]

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.

Share this post


Link to post
Share on other sites
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.

Share this post


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

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

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

Share this post


Link to post
Share on other sites

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.