This is the code I am using. As suggested I have added the headers for content type and disposition.
<?php
header('Content-Disposition: attachment');
header('Content-Type: application/octet-stream');
$con = mysql_connect("localhost","root","admin");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("acl_cake", $con);
$result = mysql_query("select * from attachments");
while($row = mysql_fetch_array($result))
{
echo 'Download--'.$row[3].'<br>';
}
mysql_close($con);
?>
Prior to addition of headers, I would have a few links available on the webpage. Whenever I would click one of them, a new page is opened and content in that file is displayed in the new page.
Now after adding the headers, whenever I load a page, I get a popup which asks me to download my form rather than the file.
If I have the content-disposition:attachment; filename='file.txt', then on page load there is a pop up to download the file "file.txt", and none of the links are displayed onto the webpage.
I am not sure if I have made a mistake with something.
I am not sure if I have made a mistake with the headers.
you need to send the content-disposition header to force a download
header("Content-Disposition: attachment; filename=\"my.file\"");
also set the content type explicitly:
header('Content-Type: application/octet-stream');
Add header Content-Disposition: attachment. See http://apptools.com/phptools/force-download.php
if i understand you right, you wan't to give your users a link to download a text-file. if so, you can do this by setting an application/octet-stream-header for this file (e.g. using php).
note: in most cases, i think you shouldn't do this. it't the users choice how to deal with files that can be opened by the browser, and if the user wan't to download such files, hea can easily configure his browser to to this or that.
Related
On a page where I offer music sample downloads, I have several <a> tags whose href points to a PHP file. Various data included as GET vars allow the proper file to be downloaded. Normally the PHP will respond with typical download headers followed by a readfile(). (the code for that is below, FYI). This results in a clean download (or download / play dialog box on some browsers). By "clean", I mean the download is completed with no disturbance in the visitors page.
However, in the unlikely event that the requested file is unavailable, I don't know what to do. I know it should not happen, but if it does I would like the download link to simply do NOTHING. Unfortunately since it is an <a> tag referencing a PHP file, doing nothing results in the browser clearing the page, with the URL of the PHP file in the address bar. Not a good visitor experience! So I'd like way to avoid disturbing the page and doing NOTHING if there is is an errant request. I'll use javascript to alert the visitor about what went wrong, but I can't have the errant file request clear the page!
I thought I'd had a solution by issuing a header('Location: #'); when the script detected an impossible file download. But after a few seconds the browser cleared the page and put up a message indicating the page "redirected you too many times." (indeed, my script log fills up with over 100 entries, even though i only clicked the tag once.)
So far the only solution I have that works (works in the sense of NOT disturbing the visitors page if an "unavailable" file is requested) is to point my download headers at a "dummy" file. An actual "silence.mp3" or "nosong.mp3" file. But is there a way to call a header() that does nothing to the calling page? Simply calling exit or exit() won't work (the visitor page is redirected a blank.)
Not that it matters, but this is the code I normally call in response to the d/l request...
function downloadFile($path) {
$path_parts = pathinfo($path);
$ext = strtolower($path_parts["extension"]); // don't need this.
$fsize =fileExists($path);
if ($fsize == 0)
{
header('Location: #'); // this doesn't work!!! (too many redirectcts)
exit;
}
//$dlname = $path_parts['filename'] . "." . strtolower($path_parts["extension"]);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: filename=\"" . $path_parts["basename"]."\"");
header("Content-Type: application/x-file-to-save");
header("Content-Transfer-Encoding: binary");
if($fsize) header("Content-length: $fsize");
$bytesRead = readfile($path);
return $bytesRead;
}
If you are using HTTP/1.x with a standard anchor tag, without JavaScript or other client-side interception. An HTTP/1.0 204 No Content status header will cause the user-agent to simply seem like nothing happened when clicking a link that returns a 204 status header.
HTTP/1.0 204 No Content
The server has fulfilled the request but there is no new information
to send back. If the client is a user agent, it should not change its
document view from that which caused the request to be generated. This
response is primarily intended to allow input for scripts or other
actions to take place without causing a change to the user agent's
active document view. The response may include new metainformation in
the form of entity headers, which should apply to the document
currently in the user agent's active view.
Source: https://www.w3.org/Protocols/HTTP/1.0/spec.html#Code204
This is also compatible with the HTTP/1.1 protocol.
I recommend using output buffering to ensure no other content is being sent by your application by mistake. Additionally there should be no need to send a Content-Length header.
function downloadFile($path) {
if (!is_file($path) || !($fsize = filesize($path))) {
header('HTTP/1.0 204 No Content');
exit;
}
$path_parts = pathinfo($path);
header('Cache-Control: public');
header('Content-Description: File Transfer');
header('Content-Disposition: filename="' . $path_parts['basename'] . '"');
header('Content-Type: application/x-file-to-save');
header('Content-Transfer-Encoding: binary');
header('Content-length: ' . $fsize); //fsize already validated above.
return readfile($path);
}
Performing the file checks before creating the links is the simplest way to do this.
If I understand your request correctly you have files that you wish to allow a client to download, and links to PHP scripts that download certain files.
The problem with your implementation is that when the file is empty, the PHP script still must load and change the content of the clients page(from the action of loading the script), which is the incorrect behavior (correct being no action at all).
Since you are using tags on the main download page, really the only way to not change the content of the page in the case of a missing file is to compute the content of the tags in advance. With a simple PHP function you could check the contents of a list of files and their directories, and then generate links for the ones that exist, and blank links for the ones that do not.
Overall, I think separating the functionality of checking whether a file exists and actually downloading the file to a client is the only way to allow the functionality you desire.
I'm sure this is a simple task, but on my wordpress site I want to create a download button that forces an .mp3 download, without opening a player (when left clicked), or the user having to right-click 'save target as'. I just need a straight forward button, that when left-clicked causes a file to be downloaded (as well as being easily trackable by Google Analytics).
Is a .php script required for this? You'd think this would be a very common function, and easy to solve....but I have spent hours on this and have been unable to get anything to work.
*if it's not obvious my coding skills are nearly non-existent.
I really appreciate anybody's time who can help me figure this out. Thanks!
***EDIT
Just found this on another post, but no comments if it would work or not. It was for a .pdf file though...
<?php
if (isset($_GET['file'])) {
$file = $_GET['file'] ;
if (file_exists($file) && is_readable($file) && preg_match('/\.pdf$/',$file)) {
header('Content-type: application/pdf');
header("Content-Disposition: attachment; filename=\"$file\"");
readfile($file);
}
} else {
header("HTTP/1.0 404 Not Found");
echo "<h1>Error 404: File Not Found: <br /><em>$file</em></h1>";
}
?>
Save the above as download.php
Save this little snippet as a PHP file somewhere on your server and you can use it to make a file download in the browser, rather than display directly. If you want to serve files other than PDF, remove or edit line 5.
You can use it like so:
Add the following link to your HTML file.
Download the cool PDF.
Well, this is possible, but you need to write a script to do it. This is a pretty poor (security and basic coding wise) from http://youngdigitalgroup.com.au/tutorial-force-download-mp3-file-streaming/
file: downloadit.php
<?php
header ("Content-type: octet/stream");
header ("Content-disposition: attachment; filename=".$file.";");
header ("Content-Length: ".filesize($file));
readfile($file);
exit;
?>
you would then place it into a publicly accessible folder and build your links as such:
http://www.yoursite.com/downloadit.php?file=/uploads/dir/file.mp3
what this does is tells the browser to treat the file as a stream of bytes, rather than a particular MIME type which the browser would ordinarily do based on the file extension.
I have a list of data compiled from a mysql recordset when I click a button on one of my pages. The data is stored in a variable $list.
It's a site activity log, and the button is a backup button.
Is there any way that I could make it open a SAVE AS dialogue box so I can save that data to a text file on my local comp?
when you click your "back up" button, you should get the user to a new script: this script should take the $list variable from the DB again and format it into a text file, then in order to make it available to the user's browser as a downloadable file, you should use headers (look at http://php.net/manual/en/function.header.php) like this:
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// The PDF source is in original.pdf
readfile('original.pdf');
?>
In this case this is a pdf file (example is from the above link). Changing the content-type to the proper mime-type ("Content-Type: text/plain" for example) and setting the right file name, all that you echo will be sent to the browser as an attached file.
If any question, ask :)
after generate that file just set the physical path of that file and throw header so it will be download at your local system
Cheers
My intention is to convert a total php page into html, and subsequently convert the html to pdf and render it through the browser.Which is done , apart from that while showing it on the browser , it will simultaneously download the pdf automatically which is not happening.
Its with PHP.
Can to tell me the basic concept ..as to how to do this.
Thanks in advance
You already render the page in the browser. Before displaying the page, header() the user to the location which will serve the same page as an attachment, but do not exit. This will allow them to download the file, but it will still load the file on the page. Not 100% sure that this will work, but it's worth a shot.
BTW different browsers will handle pdfs differently and depending on settings, plugins, etc. For instance, some might try to download the file anyway instead of showing it in the browser.
I think you need to look over the question again. As I read it, you're asking how to display something that hasn't yet been downloaded (while it's downloading), and that is obviously not possible and so cannot be what you mean.
Try creating a header, which tells the browser what to do when it receives the file.
<?php
header("Content-Type: $filedatatype" );
header("Content-Disposition: attachment; filename=\"" . $FileObject->name . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $filesize);
?>
THE EXAMPLE
1) User enters in a playlist in a <textarea>
C:/music/foo.mp3
C:/music/bar.mp3
C:/music/hello.mp3
2) They click a save button. I send the user's playlist to the server with AJAX.
3) The server formats the text with PHP in this fashion:
<playlist>
<item>C:/music/foo.mp3</item>
<item>C:/music/bar.mp3</item>
<item>C:/music/hello.mp3</item>
</playlist>
4) A file save dialog pops up asking the user to save this formatted text as playlist.m3u on their own harddrive.
QUESTIONS
A) Is it possible to not write a file to the harddrive on the server when generating this m3u file? I don't want millions of files clogging up my server. I suppose PHP can echo out the formatted text and set headers to masquerade as a file.
B) How do I get the file save dialog to pop up for this on-the-fly file? If it were a real file, I would just have the PHP respond back with the location of the file. Then I would have JS insert a new iFrame with that location. But I don't want to write a file on the server, so I can't do this.
new Ajax.Request(
'generateM3u.php',
onSuccess: function(transport) {
$$('body').first().appendChild(
new Element(
'iframe', {
src: transport.responseText
}
)
);
}
);
You should take a look at http://php.net/manual/en/function.header.php from the PHP manual. There are a lot of user contributions at the bottom of the page regarding forcing the browser to show a download prompt rather than printing to screen.
Here is one from that page (By phpnet at holodyn dot com 31-Jan-2011 09:01) which I have edited slightly. I think it answers both questions A and B. Just send the textbox's contents to the PHP file through an iframe, allow it to format the text appropriately and send it back to the browser with the following headers.
$contents = '<playlist>etc....</playlist>';
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false); // required for certain browsers
header("Content-Type: audio/x-mpegurl");
header("Content-Disposition: attachment; filename=\"playlist.m3u\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . strlen($contents));
ob_clean();
flush();
echo $contents;
Edit: If what you want is an all Javascript solution, then I personally don't know, and after a little google-ing, it looks like others don't either. Most seem to solve this with an invisible iframe that directs to a server-side file.
Edit 2: I've changed the content type so that it matches the m3u file type.
How about creating a form on your parent DOM, and post it to the IFRAME/pop-up that you created?
The POST action URL will be your generateMu3.php
To answer your questions,
A & B) I assume so... as long as generateM3u.php sets the correct MIMEType for the .m3u file...
I'm not familiar with syntax in PHP, but in both Java & .NET, you can set the response's MIMEType in the header to, say, a Word document, and the browser will read the header, and if it's a file that is "Save-able", it'll prompt the client to save the page as a file.
If I read this correctly there's a machine creating the .m3u files. In that case, perhaps just write the files to a temporary directory, /tmp on unix machines andC:\Windows\Temp on Windows machines. Those files are cleared on boot, which should allow you to handle B) without all the A).