I'm trying to view files (i.e: excel sheets/pdf/images) on browser that are stored in database.
I already wrote a code for downloading the files from the database and it is working but I want to display it in the browser.
Here is the code:
<?php require_once('Connections/databasestudents.php'); ?>
<?php
$id = $_GET['id']; // ID of entry you wish to view. To use this enter "view.php?id=x" where x is the entry you wish to view.
$query = "SELECT fileContent, filetype FROM file where id = $id"; //Find the file, pull the filecontents and the filetype
$result = MYSQL_QUERY($query); // run the query
if($row=mysql_fetch_row($result)) // pull the first row of the result into an array(there will only be one)
{
$data = $row[0]; // First bit is the data
$type = $row[1]; // second is the filename
Header( "Content-type: $type"); // Send the header of the approptiate file type, if it's' a image you want it to show as one :)
print $data; // Send the data.
}
else // the id was invalid
{
echo "invalid id";
}
?>
What happens is that view.php is downloaded and nothing is viewed.
Any suggestions?
According to your code, $row[1] is "the filename". The Content type header should contain the content type instead, i.e. the file mime type, for example:
header('Content-type: application/pdf');
If you want to add a filename:
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename='.$row[1]);
print $data;
Be sure $data is the content of the file, something you can take from readfile() for example.
Read more on the manual: http://php.net/manual/en/function.readfile.php
Keep in mind that while PDF and images are easily viewable by a browser, I think Excel needs some ad hoc plugin for that.
A more complete example right out of the manual, to get you a more thorough idea (not all those headers are necessary, and you should change others accordingly to your code):
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
Related
On my site, if a user chooses to download a file, I set a session variable called $step to "downloadEnd" and my PhP code downloads a template file using the following code:
if ($step == "downloadEnd") {
$file = "Template.xlsx";
header('Content-Description: File Transfer');
header('Content-Type: ' . $mime);
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file) . "\"");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
readfile($file);
exit();
$step = "nextStep"; // THIS IS THE LINE THAT DOES NOT EXECUTE
}
if ($step == "nextStep") {
// New Information Rendered to the User
}
The above code works, EXCEPT, that the last line of the first does not appear to 'execute'. In other words, after the download is complete, I want the user to see a new page with new text which is in a separate if statement ... if ($step == "downloadStart") ... but it never gets there. I believe it is because I need to somehow 'trick' the server into thinking there has been another user POST from the browser to the server AFTER the file downloads so that PhP iterates through all the 'if' statements and renders the new information to the user. I cannot seem to find a way to either: (i) have PhP trigger a page refresh after the file is done downloading; or (ii) trick the server into thinking it needs to refresh the page once the file is done. Any help would be appreciated.
I should add that I know the exit() at the end stops the PhP script from executing, but if you omit that line of code, the .xlsx file will be corrupted. I should also add that I tried the alternative fopen($file), fread($file), fclose($file) and that too gave me a corrupted .xlsx download, which is a problem others appear to have encountered as evidenced by other posts on Stack Overflow.
I think I see what your problem is. By running exit() you tell PHP to stop what it's doing. Try the following code:
if ($step == "downloadEnd") {
$file = "Template.xlsx";
header('Content-Description: File Transfer');
header('Content-Type: ' . $mime);
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file) . "\"");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
readfile($file);
$step = "nextStep"; // THIS IS THE LINE THAT DOES NOT EXECUTE
}
if ($step == "nextStep") {
// New Information Rendered to the User
}
Also, you might want to look into JavaScript for refreshing the page after a document has downloaded.
Edit
If you are wanting to show this like a "click link if file did not properly download" page would be then the following should work:
if ($step == "downloadEnd") {
$fileURL = "https://example.com/path/to/Template.xlsx";
echo('<script>window.open("' . $fileURL . '", "_blank");</script>');
$step = "nextStep";
}
if ($step == "nextStep") {
// New Information Rendered to the User
}
You can use something like ob_end() or ob_end_clean() but it would be better to put the new information on a separate page and redirect the user there with echo('<script>window.location.replace("new.php")</script>'). Hope that helped! Also, PHP is a server-side language and therefore cannot tell when a file has finished downloading on the client.
I want to dowload as a web-client a photo from my webserver with PHP.
Therefore, I've written the following PHP-Script:
header('Content-Description: File Transfer');
header('Content-Type: image/jpg');
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
readfile("/var/www/_old/pictures/".$filename);
($filename is the name of the file, like screenshot_03.06.2016-19:36:50.jpg)
The problem is, the content of this downloaded image is not the image itself, it's the code from the current website. The download works fine, but I cannot open the image properly ...
OK.
After some time, I found a working solution.
My problem was, that I wrote the header-commands AFTER some output. According to the php documentation, this is forbidden.
So all I did is this, I created a new .php-file and checked if the session (in which I previously stored the needed information - filename and download-command) was set correct. On the previous page, I received the POST-information, stored it into the session and redirected (also with header-command) to the newly created php-file.
Then I wrote these header-commands:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
readfile($filename);
And now, the download works from all browsers (also IE!).
Here is all my code, I hope this could help someone:
1st page (where I receive the POST-infos):
session_start();
...
...
if(isset($_POST["galerie_submitBt"])){
if($_POST["galerie_submitBt"] === "Herunterladen") { //Das Herunterladen muss in einer eigenen Datei passieren, bevor jeglichen Outputs
$_SESSION["download_Screenshot"] = true;
$_SESSION["filename"] = "/var/www/_old/pictures/".$_POST["filename"];
header("Location:modules/php/download_Screenshot.php");
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>...
2nd, new created php-page (where I actually download the image):
session_start();
if(isset($_SESSION["download_Screenshot"])){
if(isset($_SESSION["filename"]) && file_exists($_SESSION["filename"])) {
$filename = $_SESSION["filename"]; //Filename also includes the path! (absolute path)
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
readfile($filename);
unset($_SESSION["filename"]);
unset($_SESSION["download_Screenshot"]);
}
}
download.php:
<?php require_once('Connections/connection_psfriend.php'); ?>
<?php
$idreceived = addslashes($_REQUEST['sendid']);
$filepathquery = "SELECT bd_brushfilepath FROM tbl_brushdescription WHERE bd_brushid = $idreceived";
$Recordset = mysql_query($filepathquery,$connection_psfriend) or die(mysql_error());
$filepath = mysql_fetch_assoc($Recordset);
$receivedfilerequest = $filepath['bd_brushfilepath'];
$file_path = $_SERVER['DOCUMENT_ROOT'].'/'.'ps-friend'.'/' . $receivedfilerequest;
$updatedownlaodquery = "UPDATE tbl_brushdescription SET bd_brushdownloads = bd_brushdownloads + 1 WHERE bd_brushid = $idreceived";
$Recordset = mysql_query($updatedownlaodquery,$connection_psfriend) or die(mysql_error());
if(file_exists( $file_path)){
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file_path));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));
ob_clean();
flush();
readfile($file_path);
exit;
}
My problem:
The code works fine with google Chrome for all 143 entries made in the database. It works fine fine with Firefox too except for 5 out of those 143.
for firefox it shows:( for those 5 entries):
In the database, I am using filepaths to store the files. All the files are either in zip format or rar format. Those files are not downloaded in rar/zip format. With google chrome, there is no problem at all. Is there something wrong with the script?
First of all, please stop using MYSQL_ function, see why-shouldnt-i-use-mysql-functions-in-php.
Secondly you are using $idreceived = addslashes($_REQUEST['sendid']); as a nice way to prevent SQL injection. Unfortunately you are calling the query like WHERE bd_brushid = $idreceived, so without quotes.
In other words, you are still vulnerable, as long as I dont use any quotes. Consider me sending sendid=1 OR 1=1. All your rows would be updated in the second query.
Change it to WHERE bd_brushid = '$idreceived', or even better: check how-to-prevent-sql-injection-in-php
Now to your problem. I think you should change one line to the following to include quotes
header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
If it still does not work, send the right content type in the header.
<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file($finfo, $file_path);
header('Content-Type: '.$type)
?>
The following has always worked for me
$file=$_POST['file'];
header( "Content-Disposition: attachment; filename=$file" );
readfile("$_POST[file]");
without any of the content type headers.However my file extension is .zip.Your file does not seem to have an extension.
i have written a code in php which will echo a pdf file.whenever i am trying to echo that pdf,the browser page is changing into gray colors and the loading icon at the bottom left side corner is appearing and after that it fails to show that pdf file.
what i can assure you that code upto fetching the data from databse is perfect.there is no error or mistake.after fetching the data i have used following headers to echo that file.i am not sure about these headers.
$mimetype = 'application/pdf';
$disposition = 'attachment';
header('Content-type: $mimetype');
header('Content-Disposition: inline; filename="$question"');
header('Content-Transfer-Encoding: binary');
header('Content-length: ' . strlen($question));
header('Accept-Ranges: bytes');
echo "$question";
NOTE: I have used .pdf extension in content-decomposition.but that was not fruitful to me.also used readfile() function and it was also not helpful to me. Can anyone tell me what's wrong there?
The main reason why page is changing into gray colors is that the browser is unable to detect content type correctly.
Try this:
header("Content-type: $mimetype");
header('Content-Disposition: inline; filename="'.$question.'"'); // Filename should be there, not the content
Instead of :
header('Content-type: $mimetype');
header('Content-Disposition: inline; filename="$question"');
It seems that you have invalid quotes, so the content type is not specified correctly.
EDIT
To clear out, let's assume that $question is the binary PDF content.
That is what your code should be:
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename=anything.pdf');
header('Content-Transfer-Encoding: binary');
echo $question;
ERRORS EXPLAINED
Let's discuss your original code and your errors.
$mimetype = 'application/pdf';
$disposition = 'attachment';
// First error: you have single quotes here. So output is 'Content-type: $mimetype' instead of the 'Content-type: application/pdf'
header('Content-type: $mimetype');
// Second error. Quotes again. Additionally, $question is CONTENT of your PDF, why is it here?
header('Content-Disposition: inline; filename="$question"');
header('Content-Transfer-Encoding: binary');
// Also bad: strlen() for binary content? What for?
header('Content-length: ' . strlen($question));
header('Accept-Ranges: bytes');
echo "$question";
ONE MORE EDIT
i have another query...i want to change the filename into $year.pdf..$
year may have values like 2007..how can i do that???
Try this :
$year = '2013'; // Assign value
header('Content-Disposition: inline; filename='.$year.'.pdf');
Instead of:
header('Content-Disposition: inline; filename=anything.pdf');
What I want to do is to allow only one download per user (one access to a href) For that I have a variable in the user's table, which I do change when the link has been clicked.
I use "download.php?file=file.xxx" for doing that.
download.php
$file= basename($_GET['file']);
$root = "documents/rece/";
$path= $root.$file;
echo $path;
if (is_file($path))
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
readfile($path);
}
else
echo "File error";
exit();
?>
I also update the DDBB and that works. After that I can show or hide the link. The problem is that the downloaded file is corrupted and can't be opened. I will use it with pdf or doc, maybe zip.
Could it be because of the path?
PDF files, as far as I know, start with something like this:
%PDF-1.4
Yours start with 4 blank lines plus documents/rece/Form.pdf%PDF-1.4. You're obviously printing it yourself somewhere before the code you've posted.