自上传中文文件名以来,PHP无法从数据库下载上传的文件

时间:2013-09-13 03:26:26

标签: php mysql database file-upload download

对不起,我正在构建一个可以让用户将文档(pdf)上传到mysql数据库的网站。

由于我已经编写了上传和下载php页面,我可以上传文件(pdf)并成功下载英文命名文件,但无法下载名称中包含中文单词的文件。

更具体地说,我可以下载中文命名文件,但无法打开它。它表明文件已损坏。

以下是我上传的php页面代码的一部分:

        $connect = mysqli_connect("localhost", "root", "password", "table");
        if(mysqli_connect_errno($connect))//check connection
        {
               /*show error message and die*/
        }
        //set client character set to 'utf8'
        mysqli_set_charset($connect, "utf8");

        $fileName = mysqli_real_escape_string($connect, $name);
        $filePath = mysqli_real_escape_string($connect, $tmp_name);
        $fileSize = mysqli_real_escape_string($connect, $size);
        $fileType = mysqli_real_escape_string($connect, $type);
        $content = mysqli_real_escape_string($connect, file_get_contents($tmp_name));

        $filePath = addslashes($filePath);

        if(!get_magic_quotes_gpc())
        {
            $fileName = addslashes($fileName);
        }

        $teamName = $_COOKIE['teamName'];
        $reportQuery = "UPDATE uploadedreport SET name='$fileName', type='$fileType', size='$fileSize', content='$content' WHERE team='$teamName'";



        uploadFileQuery($connect, $reportQuery, $fileName);
        mysqli_close($connect);

此外,下载php页面的另一部分代码是:

    $teamName = $_COOKIE['teamName'];
    $downloadReportQuery = "SELECT name, type, size, content FROM uploadedreport WHERE team='$teamName'";


    $result = mysqli_query($connect, $downloadReportQuery);
    if($result == false)
    {
      /*alert error message and die*/
    }

    $row = mysqli_fetch_array($result);

    header("Content-length:$row[size]");
    header("Content-type:$row[type]");
    header("Content-Transfer-Encoding: binary");
    header("Content-Disposition: attachment; filename=$row[name]");//Tells the browser to save this downloaded file under the specified name

    echo $row["content"];
    mysqli_free_result($result);
    mysqli_close($connect);

有什么不对吗? 我好几天都对这个问题感到不安。

感谢您的帮助!

使用Notepad ++打开损坏的下载pdf文件: little part of downloaded pdf

我的上传页面的HTML代码:

<div id="pageDiv">
    <section id="mainSection">
        <div id="mainDiv">
            <form action="upload.php" method="post" enctype="multipart/form-data">
                <table id="mainTable">
                    <tbody>
                        <tr>
                            <td class="headColumn paragraphTitle"><label for="uploadedReport">競賽報告上傳</label></td>
                            <td><span class="hint"><span id="reportDueText"></span>截止</span></td>
                        </tr>
                        <tr>
                            <td><div id="uploadedReportDiv"><input id="uploadedReport" name="uploadedReport" type="file" required /></div></td>
                            <td><span class="hint">請以pdf格式上傳</span></td>
                        </tr>
                        <tr>
                            <td class="headColumn paragraphTitle"><label for="uploadedBriefing">競賽簡報上傳</label></td>
                            <td><span class="hint"><span id="briefingDueText"></span>截止</span></td>
                        </tr>
                        <tr>
                            <td><div id="uploadedBriefingDiv"><input id="uploadedBriefing" name="uploadedBriefing" type="file" required /></div></td>
                            <td><span class="hint">請以ppt, pptx 或pdf格式上傳</span></td>
                        </tr>
                        <tr><td colspan="2"><input id="uploadButton" type="submit" value=""/></td></tr>
                        <tr><td>&nbsp;</td><td>&nbsp;</td></tr>
                        <tr>
                            <td class="headColumn paragraphTitle">檢視已上傳檔案</td>
                            <td><a id="downloadUploadedFile" href="#">未上傳</a></td><!-- link to download file. If user has uploaded it, href will be changed by the javascript function afterUploaded -->
                        </tr>
                    </tbody>
                </table>
            </form>
        </div>
    </section>
</div>

另一方面,这是我上传页面的javascript代码:

<script>
$(document).ready(
    function()
    {
        setDateText(reportDue, "reportDueText");
        setDateText(briefingDue, "briefingDueText");

        afterUploaded();

        if(now > reportDue)
        {
            $("#uploadedReportDiv").hide();
            $("#uploadedReport").attr("required", false);
        }

        if(now > briefingDue || now <= reportDue)
        {
            $("#uploadedBriefingDiv").hide();
            $("#uploadedBriefing").attr("required", false);
        }

        $("form").submit(
            function()
            {
                var validateReport = false;
                var validateBriefing = false;

                if($("#uploadedReportDiv").is(":visible") && $("#uploadedReport").val().length > 0)
                {
                    validateReport = validateUploadedFile($("#uploadedReport").val(), "pdf");
                }
                else if(!$("#uploadedReportDiv").is(":visible"))
                    validateReport = true;

                if($("#uploadedBriefingDiv").is(":visible") && $("#uploadedBriefing").val().length > 0)
                    validateBriefing = validateUploadedFile($("#uploadedBriefing").val(), "pdf ppt pptx");
                else if(!$("#uploadedBriefingDiv").is(":visible"))
                    validateBriefing = true;


                if(!validateReport)
                    alert("檔案格式錯誤,請上傳pdf格式檔案。");//alert upload wrong file format
                if(!validateBriefing)
                    alert("檔案格式錯誤,請上傳ppt, pptx 或pdf格式檔案。");//alert upload wrong file format

                return (validateReport && validateBriefing);
            }
        );
    }
);

function setDateText(date, objectId)
{
    var dateText = (date.getFullYear()-1911) + "/" + (date.getMonth()+1) + "/" + (date.getDate());
    $("#" + objectId).text(dateText);
}

function validateUploadedFile(filename, validExtensions)
{
    var splitedArray = filename.split(".");
    var fileExtension = splitedArray[splitedArray.length-1];

    if(validExtensions.indexOf(fileExtension) == -1)
        return false;
    else
        return true;
}

function afterUploaded()
{
    if($.cookie("isUploaded"))
    {
        $("#downloadUploadedFile").attr("href", "download.php").text("下載檔案(" + $.cookie("uploadedFileName") + ")");
    }
}
</script>

谢谢!

2 个答案:

答案 0 :(得分:0)

将二进制文件数据存储在数据库中可能不是一个好主意。如果你在move_uploaded_file()PHP函数的帮助下将上传的文件移动到某个目录会更好,并且只将文件名放到数据库中。

答案 1 :(得分:0)

从您的回答中可以清楚地看到,从DB读取文件后文件不一样,所以显然有些错误。

MySQL确实支持二进制数据类型。但是,因为你可以并不暗示你应该这样做。 MySQL一次性将结果发送给客户端。因此,任何使用二进制数据解析结果集的应用程序都需要等待每一行到达才能进行处理。此外,将二进制数据存储在MySQL中没有任何实际好处。

更好的二进制数据方法是将数据存储在文件系统中,并存储指向MySQL中这些文件的指针。使用这种方法,您可以在处理结果集时实际在后台线程中传输二进制数据。

此提示不仅适用于二进制数据;它适用于任何类型的大型数据对象。困扰二进制数据的性能问题也困扰着字符数据。换句话说,结果集的任何部分的读取是连续完成的。你会更加注意二进制数据,因为它通常很大。您会注意到大字符数据的问题。您需要权衡在文件系统上存储大字符数据的性能优势与在数据库中搜索该数据的能力。

但是,如果您坚持将文件存储到数据库中,请务必使用 BLOB 类型字段。 请参阅相关的manual page here.