在PHP中下载exe文件时出现Windows兼容性错误

在PHP中下载exe文件时出现Windows兼容性错误,php,header,download,Php,Header,Download,我使用php和mysql建立了一个页面,要求用户登录下载各种付费程序。他们可以点击此处的链接,程序将正确下载并运行 $c3 = mysql_result($result,$i,"exe"); echo "<a href='$c3'>... etc 其中downloads3.php如下所示: <?php $file = $_GET['link']; $size = filesize($file); $type = filetype($file); $path = "../dow

我使用php和mysql建立了一个页面,要求用户登录下载各种付费程序。他们可以点击此处的链接,程序将正确下载并运行

$c3 = mysql_result($result,$i,"exe");
echo "<a href='$c3'>... etc
其中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不兼容。必须是上面标题中的某个内容,但无法确定是什么。尝试了各种排列


有什么好主意吗,或者是让上面的方法发挥作用,或者是用其他方法隐藏源路径?谢谢。

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

readfile($file_url);?> //PHP stops parsing here 
?> //output "\n?>"
PE头本身告诉Windows它可以在什么版本上运行,因此,如果在发送文件之前生成任何错误,它们将出现在Windows需要头的位置


为了缓解这种情况,您可以删除文件末尾的额外换行符和
?>
,并使用文件顶部的
错误报告(0)
关闭错误报告。

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

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); 

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


感谢您的评论,非常抱歉浪费您的时间。

两个问题,$type是在哪里定义的,这是在所有版本的Windows上发生的,还是仅在特定版本上发生的?我假设您已经确保直接使用该程序时真正兼容?如果您将下载的文件与其原始文件进行比较,会发生什么情况?保存每个的十六进制转储,并使用diff进行比较。看起来更像是EXE文件已损坏。如果EXE文件很大,那么在下载完成之前脚本可能会被杀死,再次使用diff on hex dumps将突出显示发生了什么。感谢所有的答案$上面的type=filetype($file),返回“file”,非常感谢所有的答案$type=上面的filetype($file),返回“file”。尝试使用“exe”,但没有不同。该程序可在所有版本的Windows上运行,直接下载即可正常运行,但不需要使用此代码。不管下载的是什么,都不是我的文件,也不是完整的文件。如果我做“另存为”,下载几乎立即完成,文件只有1kb。主机上的容量为35Mb。还删除了error?>和error rep[orting,但没有什么不同。还没有尝试过Samad的代码,但我会。Erm。但它在隐藏程序路径方面没有多大用处,这在“您想运行还是保存”消息中有说明。呵呵。
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);