【问题标题】:Bug with PHP file upload into MySQL mediumblob将 PHP 文件上传到 MySQL mediumblob 的错误
【发布时间】:2013-02-20 03:12:42
【问题描述】:

我有一个脚本,允许用户上传 DOC、DOCX、PDF 和 TXT 类型的文件。文件确实会上传,尽管没有换行符。例如,一个 TXT 文件是这样的:

//////////
THIS IS A TEXT FILE
//////////

下载回来为:

//////////THIS IS A TEXT FILE//////////

现在这不是文本文件的“大”问题,但这种换行符的丢失完全破坏了 PDF、DOC 和 DOCX 类型。

同样,在记事本中查看的 PDF 最初看起来像这样:

%PDF-1.5
%µµµµ
1 0 obj
<</Type/Catalog/Pages 2 0 R/Lang(en-US) /StructTreeRoot 10 0 R/MarkInfo<</Marked true>>>>
endobj
2 0 obj
....

但是,上传再下载后,它看起来像一个长字符串,缺少一些字符:

%PDF-1.5%µµµµ1 0 obj<>>>endobj2 0 obj

因此,当在 Adob​​e PDF 阅读器中打开文件时,它说它已损坏。


这是我用来上传文件的 PHP 脚本的摘录:

$_POST['request_id'] = $_POST['rid'];
    $tmpName = $_FILES['exam_file']['tmp_name'];
    $_POST['name'] = $_FILES['exam_file']['name'];
    $_POST['type'] = $_FILES['exam_file']['type'];
    $_POST['size'] = $_FILES['exam_file']['size'];
    //File types allowed are PDF, DOC, DOCX, TXT
    if ( ( $_POST['type'] == "application/pdf") || ($_POST['type'] == "application/msword") || ($_POST['type'] == "application/vnd.openxmlformats-officedocument.wordprocessingml.document") || ($_POST['type'] == "text/plain") ){
        $fp = fopen($tmpName, 'r');
        $content = fread($fp, filesize($tmpName));
        fclose($fp);
        $file_id = $model -> addFiles($_POST, $content);    
    }

$model中的addFiles()函数如下:

function addFiles($data, $file){
    $table = 'faculty_files';
    $data = parent::clean($data);
    $keys = array('request_id', 'name', 'type', 'size', 'content');
    $data = parent::cleanAndPick( $keys, $data );
    $data['content'] = $file;
    $data['faculty_user_id'] = $_SESSION['user_details']['id'];
    $data['inserted_on'] = date('Y-m-d H:i:s');
    parent::insert( $table, $data );
    return mysql_insert_id();
}

parent::insert() 只是将所有相关的细节,例如表名和字段,放入 SQL 语句中。

这是parent::clean() 的函数,虽然$file 没有通过它运行:

public function clean($data = NULL){
  $data = str_replace("\n", "", $data);
  $data = str_replace("\r", "", $data);
  $data = stripslashes($data);
  return mysql_real_escape_string($data);
}

函数parent::cleanAndPick()

public function cleanAndPick($keys, $data = NULL) {

    $clean = array();
    foreach ($keys as $key) {
        if (array_key_exists($key, $data))
            $clean[$key] = $this -> clean($data[$key]);
    }
    return $clean;

}

函数parent::insert()

protected function insert($table, $data ) {

    //Build sql
    $data = $this -> clean($data);
    $sql = "INSERT INTO " . $this -> clean($table);
    $sql .= " (" . implode(",", array_keys($data)) . ") VALUES (";
    foreach ($data as $value)
        $sql .= ($value == NULL ? "NULL," : "'" . $value . "',");
    $sql = substr($sql, 0, -1) . ")";
    return $this -> query($sql);

}

这是我用来下载文件的 PHP 脚本:

$file = $model -> retrieveFile($_POST['fid']);
header("Content-length: " . $file[0]['size'] . "");
header("Content-type: " . $file[0]['type'] . "");
header("Content-Disposition:attachment; filename=" . $file[0]['name'] . "");
print $file[0]['content'];

我不知道是什么导致了这个问题。如有任何意见,我将不胜感激!

编辑:有人在PHP forum 上遇到了类似的问题。摘录:

我一直在尝试上传和读取 Mac OS 文件,但未成功 Linux 服务器。许多记录仅使用 以下:

<?php $fhandle = fopen($file, 'r'); ?>    or  <?php $fhandle =
> fopen($file, 'rb'); ?> 

但是,它确实可以这样工作:

> <?php  ini_set('auto_detect_line_endings', TRUE);  $fhandle =
> fopen($file, 'r');  ?>

我确实尝试过,但它不适合我。

【问题讨论】:

  • 似乎有什么东西“吃掉”了行分隔符或将它们翻译成 UNIX (\n) 你能在 notepad++ 中打开文件吗?你看到换行符了吗?
  • Notepad++ 中没有换行符
  • 即使你启用了 UNIX 风格的行分隔符?
  • 你能输出$content吗?它看起来好吗? (换行符)?
  • 检查 blob vs. 的字节大小原件的咬合尺寸。如果在上传期间/之后有东西吃掉换行符,那么 blob 应该更小。请注意,如果您不提供 b 选项以二进制(非翻译)模式读取它,那么 fread 可能 会为您翻译行尾。

标签: php mysql file-upload blob multipartform-data


【解决方案1】:

如果您不想对其内容进行任何更改,请使用fopen($tmpName, 'rb');。

然后是这个:

protected function insert($table, $data ) {
  //Build sql
  $data = $this -> clean($data); //<---- here......

【讨论】:

  • 添加 cleanAndPick、插入和清理
  • $data = parent::cleanAndPick( $keys, $data ); 在我声明$data['content'] = $file; 之前运行,所以$data['content'] = $file; 没有被触及?
  • 可以运行$file 到mysql_real_escape_string() 吗?没有它,我会在 SQL 中收到错误...
  • 是的,完全没问题,就其本质而言,它应该按原样保留数据(当在查询中使用时)。
猜你喜欢
  • 2014-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 2010-09-05
  • 2012-05-04
相关资源
最近更新 更多