【问题标题】:PHP - BLOB not inserting into MySQL databasePHP - BLOB 未插入 MySQL 数据库
【发布时间】:2015-12-24 21:14:54
【问题描述】:

我正在尝试创建一个页面,有人可以在其中上传文档或图像,并将其存储在 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 中,这个值在表中只是空的。如果我错了,请纠正我,但它不应该显示价值吗?只是为了仔细检查我是否正确,我创建了一个脚本来下载文件,但是当我打开文件时,它会显示为一个空文件。

这是脚本:

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()。不需要这样做,因为参数化查询负责转义。不知道 PMA 对 blob 列的行为是什么。如果你想验证一些东西,你最好跳过它,直接进入 MySQL 控制台。
  • @miken32 我评论了这条线,但它仍然不起作用。奇怪。
  • 什么是$abstractID?你的下载代码是给你一个损坏的文件还是一个空的文件?此外,您的程序中有拼写错误:DELIMETER
  • 它是表 Abstract 的外键,当表单被提交并正确插入到 AbstractAttachments 表中时,它是从不同的查询中检索到的。还有一个空文件。那只是我写帖子时的错误,程序确实编译正确,我将其编辑出来。
  • 好吧,我希望看到它从外部传递给insertAbstract(),这就是我问的原因。有任何关于损坏与空的更新吗?

标签: php mysql blob


【解决方案1】:

我不擅长使用sql程序,在mysql数据库中创建表后尝试以下代码,它会工作 .如果它真的解决了您的问题,请标记为正确答案...

sql

create table customer_account (photo_id int(55) primary key auto_increment,photo longblob,name varchar(88),account_no integer(86),address varchar(72),email varchar(45));

html

<html>
  <body>
    <font color=green size=4>upload Passport Photograph of aCustomer<BR>
    Using PHP Uploads Technology</font></b><br>     
    <form method="post" action="upload.php"  enctype="multipart/form-data">
      <table class="main">
        <tr>
          <td class="header" colspan="2">General Account Opening Form Along with Passport Photograph of the Customer<BR>
            Using PHP Uploads Technology
          </td>
        </tr> 
        <tr>
          <td>Photo</td>
          <td><input type="file" name="photo_upload" class="long"></td>
        </tr>
        <tr>
          <td>Name</td>
          <td><input type="text" name="name" class="long"></td>
        </tr>
        <tr>
          <td>Account Number</td>
          <td><input type="text" name="account_no" class="long"></td>
        </tr>
        <tr>
          <td>Address</td>
          <td><input name="address" type="text"></td>
        <tr>
           <td>Email</td>
            <td><input name="email" type="TEXT"></td>
        </tr>
        <tr>
          <td colspan="2"><input type="submit" value="Register!" /></td>
        </tr>
      </table>
    </form>
  </body> 
</html> 

上传.php

<?
$mysqli = new mysqli("localhost", "nickolysis_username", "nick_password", "photo_database");

$photo_upload='';// variable photo is set to photo_upload
$name=mysql_real_escape_string($_POST['name']);
$account_no=mysql_real_escape_string($_POST['account_no']);
$address=mysql_real_escape_string($_POST['address']);
$email=mysql_real_escape_string($_POST['email']);

$stmt = $mysqli->stmt_init();

// read image with variable read_customerphoto and then insert into database    
move_uploaded_file($_FILES['photo_upload']['tmp_name'],"customerphoto.img");
        $read_customerphoto = fopen("customerphoto.img","rb");
        $photo = addslashes(fread($read_customerphoto,filesize("customerphoto.img")));

if($stmt->prepare("insert into customer_account(photo,name,account_no,address,email) VALUES (?, ?, ?, ?, ?)")) {
  $photo_id= mysql_insert_id();
  $stmt->bind_param('ssiss',$photo,$name,$account_no,$address,$email);
  $stmt->execute();

  // Close statement object
  $stmt->close();
  print "<font size=4 color=green>upload is successful</font> ";
}
else{
  print "error";
}
/* close connection */
$mysqli->close();
?>

【讨论】:

  • 复制和粘贴不相关的代码并不能提供问题的答案。
【解决方案2】:

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

绑定变量与查询分开发送到服务器,因此不会干扰它。在解析语句模板之后,服务器直接在执行点使用这些值。 绑定参数不需要转义,因为它们从不直接替换到查询字符串中。必须向服务器提供绑定变量类型的提示,以创建适当的转换。

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

    $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()。我一直将文件存储在文件系统中,并建议您这样做!)

最后,您执行的每个数据库函数——打开连接、准备语句、绑定参数和执行语句——都应该有其结果checked for errors。即使没有错误,MySQL 仍然可以生成 non-fatal warnings,这可能会导致错误值未被插入。

【讨论】:

  • 我将 SQL 语句从准备好的语句更改为显式语句,现在它可以工作了。所以我怀疑我的程序不喜欢 BLOB。任何想法该程序可以做什么?
  • 我发现了问题所在。事实证明,它不喜欢 BLOB 作为准备好的语句的参数类型。当我将其更改为字符串时,它接受了它,现在在表格中正确显示。所以这很奇怪。
猜你喜欢
  • 2011-10-26
  • 1970-01-01
  • 2019-09-25
  • 2014-04-04
  • 1970-01-01
  • 2012-10-19
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多