HIRA THAKUR
HIRA THAKUR

Reputation: 17757

force Download file in php?

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?

Upvotes: 0

Views: 661

Answers (2)

The Marlboro Man
The Marlboro Man

Reputation: 971

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.

Upvotes: 1

Elon Than
Elon Than

Reputation: 9775

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>

Upvotes: 3

Related Questions