PHP - BLOB 未插入 MySQL 数据库

标签 php mysql blob

我正在尝试创建一个页面,人们可以在其中上传文档或图像,并将其存储在 MySQL 数据库中,但是,由于某种原因,文档/图像的内容实际上并未插入到我创建的表。奇怪的是,表中的其余列都已填充,只有一个 LONGBLOB 列未填充。

以下是表单的 HTML 代码:

<form method="post" enctype="multipart/form-data">
        <input type="submit" value="Submit" />
        <input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
        <label>Select Event:</label>
           <select name="eventID">
              <?php
                 foreach($data as $e)
                 {
                     echo "<option value='" . $e["eventID"] . "'>" . $e["name"] . "</option>";
                 }
              ?>
          </select>

          <label>Your ID:</label>

          <input name="contributorID" type="number" min="0" />

          <label>Your Abstract:</label>

          <textarea name="abstract" rows="10" cols="50"></textarea>

          <label>Attachment:</label>

          <input type="file" name="attachment" />

</form>

我相信我的形式是正确的,并确保具有最大值的隐藏字段存在并且编码是正确的。

这是处理表单 POST 的 PHP 代码:

$abstract = $this->model("Abstracts");

if (!empty($_FILES["attachment"]) && ($_FILES["attachment"]["error"] == 0))
{
    $fileName = $_FILES["attachment"]['name'];
    $tmpName  = $_FILES["attachment"]['tmp_name'];
    $fileSize = $_FILES["attachment"]['size'];
    $fileType = $_FILES["attachment"]['type'];

    //$fp = fopen($tmpName, 'r');
    $content = file_get_contents($tmpName);
    $content = addslashes($content);
    //fclose($fp);

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

    $abstract->insertAbstract($_POST["contributorID"], $_POST["eventID"], $_POST["abstract"], $content, $fileName, $fileType, $fileSize);
}

Abstracts 类的 insertAbstract 方法:

public function insertAbstract($contributorID, $eventID, $abstract, $attachment = null, $name = null, $type = null, $size = null)
{
    $conn = new Credentials;
    $this->connection = $conn->conn;

    if (!empty($attachment))
    {
        $query = $this->connection->prepare("CALL sp_PopulateAbstractAttachments(?,?,?,?,?)");
        $query->bind_param("ibssi", $abstractID, $attachment, $name, $type, $size);

        $query->execute();

        $query->close();
    }

    mysqli_close($this->connection);
}

存储过程背后的SQL:

CREATE PROC...
(abID INT, att LONGBLOB, n VARCHAR(500), t VARCHAR(30), s INT)
BEGIN
    DELETE
    FROM abstractattachments
    WHERE abstractID = abID;

    INSERT INTO abstractattachments
    (abstractID, attachment, name, type, size)
    VALUES (abID, att, n, t, s);
END

该行插入了正确的 abIDnts,但 attn 似乎没有。在 phpMyAdmin 中,该值在表中为空。如果我错了请纠正我,但它不应该显示值(value)吗?为了再次检查我是否正确,我创建了一个脚本来下载文件,但是当我打开该文件时,它显示为一个空文件。

这是脚本:

public function downloadAbstract()
{
   //instantiates connection object from credentials.php
   $conn = new Credentials;
   $this->connection = $conn->conn;

   //manually change attachmentID parameter for script
   $query = "SELECT name, type, size, attachment FROM AbstractAttachments WHERE attachmentID = 22";

   $this->result = mysqli_query($this->connection, $query);
   list($name, $type, $size, $attachment) = mysqli_fetch_array($this->result);

   header("Content-length: $size");
   header("Content-type: $type");
   header("Content-Disposition: attachment; filename=$name");
   echo $attachment;

   mysqli_close($this->connection);
   exit;
}

我在这里迷失了方向,所以欢迎任何指导。我已尝试尽可能地压缩代码。

最佳答案

首先,使用 addslashes() 可能会损坏您存储的文件。你不想这样做,因为 the parameterized query takes care of escaping :

Bound variables are sent to the server separately from the query and thus cannot interfere with it. The server uses these values directly at the point of execution, after the statement template is parsed. Bound parameters do not need to be escaped as they are never substituted into the query string directly. A hint must be provided to the server for the type of bound variable, to create an appropriate conversion.

我们在评论中发现的另一个问题是,您的数据库未配置为允许向其传递如此大的参数。您可以尝试使用send_long_data()将参数以较小的 block 传递到数据库。

    $query = $this->connection->prepare("CALL sp_PopulateAbstractAttachments(?,?,?,?,?)");
    $query->bind_param("ibssi", $abstractID, null, $name, $type, $size);
    foreach (str_split($attachment, 10240) as $chunk) {
        $query->send_long_data(1, $chunk);
    }
    $query->execute();
    $query->close();

(完全公开,我以前从未使用过 send_long_data()。我一直将文件存储在文件系统中,并建议这样做!)

最后,您执行的每个数据库函数(打开连接、准备语句、绑定(bind)参数和执行语句)都应该有其结果 checked for errors 。即使没有错误,MySQL仍然可以产生non-fatal warnings这可能会导致诸如无法插入错误值之类的情况。

关于PHP - BLOB 未插入 MySQL 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34457958/

相关文章:

php - 如何在另一个类中使用$PDO变量?

php - caching_sha2_password mysql错误

php - 错误 SQLSTATE[42000] Laravel 更新

mysql - 从复杂查询中定义 mysql 中的 View - 尝试 #2

java - 将图像保存在 Oracle 中,稍后无需检索 BMP

javascript - jQuery 旋钮释放功能附加参数

mysql - 按允许或阻止的值过滤 50k+ 行

php - 为什么没有捕获到 PDO 异常错误?

ASP.net 与 blob 的连接

java - 在 mySQL 和 hibernate 之间映射 MediumBlob