在PHP中下载exe文件的Windows兼容性错误

时间:2012-02-28 14:23:53

标签: php header download

我已经使用php和mysql设置了一个页面,要求用户登录以下载各种付费节目。他们可以点击这里的链接,程序下载并正确运行。

$c3 = mysql_result($result,$i,"exe");
echo "<a href='$c3'>... etc

但是,RT-click属性允许他们查看该文件的路径,因此我将上述内容更改为:

$c3="downloads3.php?link=".mysql_result($result,$i,"exe");

其中downloads3.php如下:

<?php
$file = $_GET['link'];
$size = filesize($file);
$type = filetype($file);
$path = "../downloads/";
header('Content-Type: $type'); 
header("Content-Transfer-Encoding: Binary");  
header("Content-Disposition: attachment; filename=$path.$file");
header("Content-Length: ".filesize($file)); 
readfile($file_url);?> 
?>

它找到了正确的文件并且我收到了安全警告,但是在点击运行时它仍然会立即显示一条Windows错误消息,指出该文件与此版本的Windows不兼容。必须是上面标题中的内容但无法弄清楚是什么。试过各种排列。

任何明智的想法,无论是上述工作还是隐藏源路径的其他方式?感谢。

3 个答案:

答案 0 :(得分:1)

由于意外输出,EXE更有可能被破坏。您的downloads3.php文件会在下载中显示一些额外的输出:

readfile($file_url);?> //PHP stops parsing here 
?> //output "\n?>"

PE标头本身告诉Windows它可以运行哪些版本,因此如果在文件发送之前生成任何错误,它们将出现在Windows期望标题的位置。

要缓解此问题,您可以删除文件末尾的额外换行符和?>,并通过文件顶部的error_reporting(0)关闭错误报告。

答案 1 :(得分:1)

这里的最佳解决方案是获取您想要的任何名称的下载文件

function force_download($filename = '', $data = '')
{
    if ($filename == '' OR $data == '')
    {
        return FALSE;
    }

    // Try to determine if the filename includes a file extension.
    // We need it in order to set the MIME type
    if (FALSE === strpos($filename, '.'))
    {
        return FALSE;
    }

    // Grab the file extension
    $x = explode('.', $filename);
    $extension = end($x);

    // Load the mime types
    if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT))
    {
        include(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT);
    }
    elseif (is_file(APPPATH.'config/mimes'.EXT))
    {
        include(APPPATH.'config/mimes'.EXT);
    }

    // Set a default mime if we can't find it
    if ( ! isset($mimes[$extension]))
    {
        $mime = 'application/octet-stream';
    }
    else
    {
        $mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
    }

    // Generate the server headers
    if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
    {
        header('Content-Type: "'.$mime.'"');
        header('Content-Disposition: attachment; filename="'.$filename.'"');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header("Content-Transfer-Encoding: binary");
        header('Pragma: public');
        header("Content-Length: ".strlen($data));
    }
    else
    {
        header('Content-Type: "'.$mime.'"');
        header('Content-Disposition: attachment; filename="'.$filename.'"');
        header("Content-Transfer-Encoding: binary");
        header('Expires: 0');
        header('Pragma: no-cache');
        header("Content-Length: ".strlen($data));
    }

    exit($data);
}

$data = 'Here is some text!';
$name = 'mytext.txt';

force_download($name, $data); 

答案 2 :(得分:0)

DOH !!!!!!!!!!!!!!!!太多的剪切和粘贴,那个代码有一个非常愚蠢的错误readfile($ file_url)应该是readfile($ file),难怪我的36Mb文件下载后只有1KB,它是空的!

感谢所有的评论,为浪费你的时间道歉。