header()下载损坏的文件

时间:2014-04-28 22:33:30

标签: php download

为什么此代码不起作用,url是声音文件:

header("Location: http://biencaleta.com/musica/Billboard-70s/Grupos/Billboard%201970.ca/Simon Y Garfunkel - Bridge Over Trubled.msa");

浏览器(chrome)只是播放它而不是下载它,但它确实适用于http://23.250.9.10/~caletaco/Alkilados - Mona Lisa.msa我也尝试过:

$file='http://biencaleta.com/musica/Billboard-70s/Grupos/Billboard%201970.ca/Simon Y Garfunkel - Bridge Over Trubled.msa';
$basename = basename($file);

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $basename . '"');
header('Content-Transfer-Encoding: binary');

set_time_limit(0);
readfile($file);

但它下载了一个损坏的文件。 感谢

1 个答案:

答案 0 :(得分:0)

将空格留在原位,您要求的网址无效。您的浏览器会为您处理,但您必须使用PHP进行合作。

从文件名开始:

$url="http://biencaleta.com/musica/Billboard-70s/Grupos/Billboard 1970.ca/Simon Y Garfunkel - Bridge Over Trubled.msa";

...我们会在其上使用explode将网址分解为各种网址:

$url= explode('/', $url);

现在我们有一个数组:

var_dump($url);
/*
array (size=8)
  0 => string 'http:' (length=5)
  1 => string '' (length=0)
  2 => string 'biencaleta.com' (length=14)
  3 => string 'musica' (length=6)
  4 => string 'Billboard-70s' (length=13)
  5 => string 'Grupos' (length=6)
  6 => string 'Billboard 1970.ca' (length=17)
  7 => string 'Simon Y Garfunkel - Bridge Over Trubled.msa' (length=43)
 */

在该数组中,您有许多需要进行URL编码的部分。 PHP有一个函数,称为rawurlencode。但是,您不能简单地将整个网址投放到该函数中,因为它会编码我们不想要的http://部分。

我们将保存协议,并删除该空白项目(它来自" //"部分网址):

$protocol = array_shift($url); // save this
array_shift($url);             // throw this out

现在,您可以安全地编码其余部分:

foreach ($url as &$part)
    $part = rawurlencode($part);

......并将它们重新组合在一起

$url = $protocol.'//'.implode('/', $url);

将现在编码的网址与原始网址进行比较:

 enc: http://biencaleta.com/musica/Billboard-70s/Grupos/Billboard%201970.ca/Simon%20Y%20Garfunkel%20-%20Bridge%20Over%20Trubled.msa
orig: http://biencaleta.com/musica/Billboard-70s/Grupos/Billboard 1970.ca/Simon Y Garfunkel - Bridge Over Trubled.msa

......看起来不错。现在我们可以获取内容并设置下载:

$contents = file_get_contents($url);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$cleanName.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
die($contents);

你可能会注意到那里的$cleanName变量......那是什么?在字符串被编码并且看起来很杂乱之前,您可以抓住basename - 正确之前将其爆炸。把它们放在一起:

$url = "http://biencaleta.com/musica/Billboard-70s/Grupos/Billboard 1970.ca/Simon Y Garfunkel - Bridge Over Trubled.msa";
$cleanName = basename($url);
$url = explode('/', $url);

$protocol = array_shift($url);
array_shift($url);

foreach ($url as &$part)
    $part = rawurlencode($part);
$url = $protocol.'//'.implode('/', $url);

$contents = file_get_contents($url);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$cleanName.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
die($contents);

<强>文档

相关问题