上传文件下载时文件名问题

#1 coolcool1265

多个文件上传时,一般我们会选择使用时间戳对要保存的文件进行重命名,时间戳就是文件存储的名字;
而将文件名存储到数据库中。例如:

a.doc    -----上传后----->    文件名:a
                                        扩展名:doc
                                        存储时的名字:5beff94b049ac364195e78b86c8bcf42


但是如果文件要下载,就要下载用时间戳重命名的文件,直接下载成了:5beff94b049ac364195e78b86c8bcf42.doc,而不是   a.doc


请问 有什么好办法吗?
-------------------------------------------------------

下面是我找到的资料,但是看不来怎么做。请高手指点。最好能提供一个例子。


$ua = $_SERVER["HTTP_USER_AGENT"];
$filename = "中文 文件名.txt";
$encoded_filename = urlencode($filename);
$encoded_filename = str_replace("+", "%20", $encoded_filename);
header('Content-Type: application/octet-stream');
if (preg_match("/MSIE/", $ua)) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
header('Content-Disposition: attachment; filename*="utf8\'\'' . $filename . '"');
} else {
header('Content-Disposition: attachment; filename="' . $filename . '"');
}





php 下载主要就三点吧
1。得到文件$file
2。书写固定的html头部
header("")
比如
header("Content-Type:text/plain");
header("Accept-Ranges:bytes");
header("Accept-Length:".filesize($file));
header("Content-Disposition: attachment;filename=".basename($file));
3。打开文件并读取
比如
$fp = fopen($filename, 'rb');
@flock($fp,2);
$downloadfile = fread($fp, filesize($file));
@fclose($fp);
echo $downloadfile;
一般这样就可以了吧

2011-05-04 00:14:43

#2 jake

一般我们会这样设计:在数据表中存上传的原文件名,和新的时间戳文件名,在下载的时候,使用原文件名。

header("Content-Disposition: attachment;filename=".从数据库中读取到的原文件名);

2011-05-04 02:57:00

#3 coolcool1265

思路很清晰,我的数据库中也是这么设计的。一个是真实的文件名,一个是时间戳名。

但下面的这个代码具体应该怎么用呢?我前台用的是smarty代码。
header("Content-Disposition: attachment;filename=".从数据库中读取到的原文件名);
例如:

下载文件


我该怎么把header加入呢?header还是php的代码


<{php}>
header("Content-Disposition: attachment;filename=".从数据库中读取到的原文件名);

下载文件

<{/php}>

上面那样子写肯定是不行的。




从下面的例子可以看出,你保存的文件是什么,是和你print相同的。难道我要吧下载的文件打开一遍,然后重新写入到“真实文件名”的文件中,然后再保存吗?

希望能给个简单的例子。

$filename = "document.txt";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
print "Hello!";
?>

2011-05-04 18:41:37

#4 jake

文件物理路径和文件原文件名都应该是存到数据库中的一条记录里面的,取的时候也一起取。

假设用的是speedphp框架,这里是控制器内的一个action页面,根据传入的id下载某文件

$id = $this->spArgs('id');
$info = spClass('tbl_download')->find(array('id'=>$id)); //  获取到数据库记录
$file_path = $info['file_path']; // 物理文件路径,在file_path字段中
$file_name = $info['file_name']; // 原文件名,在file_name字段中
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $file_name ); // 发送原文件名
echo file_get_contents($file_path); // 读取文件内容

因为是下载,所以不建议用smarty,直接通过php的header发送文件内容即可。

2011-05-04 20:52:26

#5 coolcool1265

非常感谢jake老大

:victory:O(∩_∩)O谢谢,已经搞定了


再次感谢!

以下是详细的代码,请参考。
 
function downloadfile(){
  $id = $this->spArgs('fileid');
  $info = spClass('stuworkModel')->find(array('workid'=>$id)); //  获取到数据库记录
  $file_path = $info['file_path']; // 物理文件路径,在file_path字段中


  $ua = $_SERVER["HTTP_USER_AGENT"];
  $filename =$info['workname']; // 原文件名,在file_name字段中

  $encoded_filename = urlencode($filename);  
  $encoded_filename = str_replace("+", "%20", $encoded_filename);  
  header('Content-Type: application/octet-stream');  
  if (preg_match("/MSIE/", $ua)) {  
  header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');  
  } else if (preg_match("/Firefox/", $ua)) {  
   header('Content-Disposition: attachment; filename*="utf8\'\'' . $filename . '"');  
  } else {  
  header('Content-Disposition: attachment; filename="' . $filename . '"');  
   }  
  echo file_get_contents($file_path); // 读取文件内容

}

2011-05-04 21:33:33

#6 vsxp

观望者。:P

2011-05-05 17:07:48

#7 vsxp

观望者。:P

2011-05-05 17:07:55