k09
May 24, 2011, 11:11am
1
Hi,
I have uploaded ms word docs and pdfs to my site.
How do I use PHP to allow user to open files from my site? They click on a link and the file should open in either MS Word or Adobe Reader.
How do I use headers for this?
header("Content-type: application/pdf");
Thanks.
rpkamp
May 24, 2011, 11:13am
2
Take a look at [fphp]readfile[/fphp]
The header you have there is okay, but you might want to add a Content-Disposition to force browser to download the file, rather than show it inline.
header("Content-type: application/pdf");
header("Content-Disposition: attachment");
readfile("/path/to/my/file.pdf");
k09
May 24, 2011, 11:22am
3
rpkamp:
Take a look at [fphp]readfile[/fphp]
The header you have there is okay, but you might want to add a Content-Disposition to force browser to download the file, rather than show it inline.
header("Content-type: application/pdf");
header("Content-Disposition: attachment");
readfile("/path/to/my/file.pdf");
Thanks.
Have the below code. But I want to read files from 2 different directories. How do I set the correct filepath based on which file the user clicked?
$path = "/documents/policy/"; // change the path to fit your websites document structure
$fullPath = $path.$_GET['download_file'];
if ($fd = fopen ($fullPath, "r"))
{
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-type: application/pdf"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\\"".$path_parts["basename"]."\\""); // use 'attachment' to force a download
break;
case "doc":
header("Content-type: doc"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\\"".$path_parts["basename"]."\\""); // use 'attachment' to force a download
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\\"".$path_parts["basename"]."\\"");
}
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
Thanks!
rpkamp
May 24, 2011, 12:04pm
4
2 different directories how? one for pdf and one for doc? in that case you need to set the path in the switch, not before it.
BTW. You have a huge security hole in there. Consider this
yourdownloader.php?file=../../etc/passwd
…
k09
May 24, 2011, 12:16pm
5
rpkamp:
2 different directories how? one for pdf and one for doc? in that case you need to set the path in the switch, not before it.
BTW. You have a huge security hole in there. Consider this
yourdownloader.php?file=../../etc/passwd
…
That is the code I have been getting online.
This is the actual download link code…
// load available files
$current_dir = 'documents/education/';
if ($handle = opendir($current_dir))
{
$i=0;
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
$files[$i] = $file;
$i++;
}
}
closedir($handle);
}
sort($files);
for($i=0; $i<sizeof($files); $i++)
{
$currentfile = $current_dir.rawurlencode($files[$i]);
//echo $currentfile;
//echo '<li><a href='.$currentfile.'>'.$files[$i].'</a></li>';
echo '<li><a href=education.php?download_file='.$currentfile.'>'.$files[$i].'</a></li>';
}
And the updated header code, which I got from php manual …
$file = $_REQUEST['download_file']; // documents/education/test.docx
echo 'FILE:'.$file;
if (file_exists($file)) {
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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
$file is blank. Why is this?
rpkamp
May 24, 2011, 12:32pm
6
Does it show a value in the HTML? If so maybe $_REQUEST doesn’t work as expected on your host; try $_GET (which is more appropriate than $_REQUEST anyway).
k09
May 24, 2011, 12:38pm
7
k09
May 24, 2011, 12:49pm
8
OK. This is my entire code education.php. I would be very grateful if you could point where I am going wrong.
Thanks!
<?php
session_start();
$file = $_GET['download_file']; // documents/education/test.docx
//echo 'FILE:'.$file;
ECHO $_GET['download_file'];
if (file_exists($file)) {
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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="mainContent">
<h1>Education</h1>
<?php
echo '<p>Available Documents:</p>';
echo '<ul>';
// load available files
$current_dir = 'documents/education/';
if ($handle = opendir($current_dir))
{
$i=0;
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
$files[$i] = $file;
$i++;
}
}
closedir($handle);
}
sort($files);
for($i=0; $i<sizeof($files); $i++)
{
$currentfile = $current_dir.rawurlencode($files[$i]);
echo $currentfile;
//echo '<li><a href='.$currentfile.'>'.$files[$i].'</a></li>';
echo '<li><a href=education.php?download_file='.$currentfile.'>'.$files[$i].'</a></li>';
}
echo '</ul>';
?>
</div> <!-- #end mainContent-->
That href needs quoting
echo '<li><a href="education.php?download_file='.$currentfile.'">'.$files[$i].'</a></li>';
Have you thought about how to solve that massive security hole yet?
k09
May 24, 2011, 2:01pm
10
Ensure proper database login? Is my script fine otherwise?
rpkamp
May 24, 2011, 2:23pm
11
Yes your script looks fine otherwise. Ensuring a database login will help, but not secure it in the best way (because you’re hiding it, rather than really securing it). What you want is
$file=ltrim($_GET['download_file'], './');