尝试通过PHP/MySQL下载Blob文件

3

有件事情我就是想不通:我已经在网页上成功地建立了上传功能,可以将文件上传到MySQL数据库。当我在服务器上通过phpMyAdmin打开它们时,它们看起来都很好...... txt、jpg、pdf等。

然而,在我写下面这个下载功能后,出现了一个奇怪的问题:所有文本文档(以及所有其他类型的文件,在我将扩展名改为'txt'后)都包含页面本身的HTML代码,后跟原始内容!

此外,在POST之后,不同的浏览器显示的方式也不同。当尝试下载txt文件时,IE会在页面的ECHO中显示正确的数据(没有下载),并在其前面显示错误消息:

Warning: Header may not contain more than a single header, new line detected. in C:\wamp\www\ace\dmain.php on line 82.

Line 82 is 'header("Content-length...'

Firefox和Chrome都不会显示任何东西,它们只允许我下载。

以下是代码:

<?php
if (isset($_POST['downloadid'])) {
    $fileid = $_POST['downloadid'];
    try {
      $sql = "SELECT * FROM `datastore` WHERE `id` = '".$fileid."'";
        $results = $pdo->query($sql);echo $sql;
        while ($row = $results->fetch()) {
            $filename = $row['filename'];
            $mimetype = $row['mimetype'];
            $filedata = $row['filedata'];
            header("Content-length: strlen($filedata)");
            header("Content-type: $mimetype");
            header("Content-disposition: download; filename=$filename"); //disposition of download forces a download
            echo $filedata; 
            // die();
        } //of While
    } //try
    catch (PDOException $e) {
        $error = '<br>Database ERROR fetching requested file.';
        echo $error;
        die();    
    } //catch
} //isset
?>

3
哎呀,你正在使用PDO但仍然没有绑定参数,这使得你容易受到SQL注入攻击的威胁。请(为了自己好)研究一下PDO中的bindValue和prepare方法。你还在修改头部之前使用echo输出SQL语句。如果没有启用输出缓冲,这将导致头部无法发送。 - Colin M
是的...我是个坏孩子。这只是供一小部分员工内部使用的,但我明白了。我会重写它。 - Chris Wilson
即使是内部使用,这也很重要。如果代码是这样编写的话,离职员工在离开时造成一些损害是很难阻止的!我只是想帮助你。但是在您的内部组织中,您比我更清楚情况。 - Colin M
当只涉及输出时,我是否仍应绑定参数并使用prepare? - Chris Wilson
是的,你应该 始终 进行转义。相信我,如果你问自己“我应该转义 X 吗?”并且总是回答“是”,那么你将为自己和公司做出一个好处。 - Colin M
3个回答

6
这是:

header("Content-length: strlen($filedata)");

这不会产生您期望的结果。如果您查看wireshark中的头文件或其他查看请求的方法,您会发现它不包含整数。

请改用以下方法:

header("Content-length: ".strlen($filedata));

谢谢你!我不再收到IE的消息了,但是所有文件仍然在开头附加有HTML代码。烦死了。 - Chris Wilson
你的代码目前正在回显SQL语句,你在回显文件数据之前有其他输出吗? - datasage
我在发布后删除了echo $sql。但是没有运气。在<?PHP标记之前还有其他输出。 - Chris Wilson
不需要。只需从我的头文件开始,连续滚动到页面底部。文件中包含所有页面HTML。我已经阅读过空格和输出之前可能会破坏此操作的内容。我应该通过表单调用一个单独的、隔离的PHP页面吗? - Chris Wilson
我认为你需要进行隔离。你需要确保它在没有生成其他HTML的上下文中被调用。 - datasage
谢谢。我刚刚做了那个,问题已经解决了。我不是很明白。所有其他代码看起来都没问题。只是标题的一个小问题? - Chris Wilson

0

在苦苦思索是否要在原地修复它(也就是在同一页的HTML和代码中),我决定将其移动到专门的PHP页面上。之后,它正常工作了。

感谢您的评论!


-1

我认为这要么过时了,要么是垃圾邮件。 - Balazs Gunics

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接