将文件保存为数据库ajax​​ php pdo中的blob

时间:2015-04-14 08:14:44

标签: php mysql ajax pdo blob

$fileCount = count($_FILES);
for ($i = 0; $i < $fileCount; $i++) {
    $fp = fopen($_FILES["file_".$i]['tmp_name'], 'rb');
    $stmt4 = $dbh - > prepare("INSERT INTO files_tbl (pin,remarks,fileblob,file_type,nameoffile,filesize) VALUES (?,?,?,?,?,?)");
    $stmt4 - > bindValue(1, $pin, PDO::PARAM_STR);
    $stmt4 - > bindValue(2, $remarks, PDO::PARAM_STR);
    $stmt4 - > bindParam(3, $fp, PDO::PARAM_LOB);
    $stmt4 - > bindParam(4, $_FILES["file_".$i]['type'], PDO::PARAM_STR);
    $stmt4 - > bindValue(5, $_FILES["file_".$i]['name'], PDO::PARAM_STR);
    $stmt4 - > bindValue(6, $_FILES["file_".$i]['size'], PDO::PARAM_STR);
    $stmt4 - > execute();
}

这是我如何在php中插入文件作为blob。它正在保存文件但是没有正确保存。当我说它没有正确保存时,我的意思是一路上出了问题。当我比较使用我的项目保存文件并在XAMPP中手动添加文件时,fileblob存在差异,例如我在xampp中手动保存文件,当我使用项目变为{{1}时,fileblob为[BLOB - 488.9 KiB] }。我认为这是我尝试从数据库显示文件的原因,它显示一个空白页面(当我显示的文件是我使用项目插入的文件)但如果我试图显示的文件是我在xampp手动插入的文件它显示文件。

我的插入可能有什么问题?为什么我没有保存正确的blob

[BLOB - 479.2 KiB]

UPDATE

AJAX

<input type="file" id="filecontent" name="filecontent" multiple="">

var file = $('#filecontent')[0].files; for (var i = 0; i < file.length; i++) { formData.append("file_" + i, file[i]); //more data are passed to formData //formData.append("file", file[i]); console.log(file[i]); } $.ajax({ url: '../include/AddNew.php', type: 'POST', dataType: "json", data: formData, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success: function(data) { console.log(data); alert(data.message); //window.location.reload(true); }, error: function(data) { //alert("Error!"); // Optional } });

当我尝试将UPDATE放在行print_r($_FILES);之前时输出为

for ($i = 0; $i < $fileCount; $i++) {

Array ( [file_0] => Array ( [name] => whomovedmycheese - Copy.pdf [type] => application/pdf [tmp_name] => C:\Users\HogRider\xampp\tmp\phpE775.tmp [error] => 0 [size] => 500624 ) [file_1] => Array ( [name] => whomovedmycheese.pdf [type] => application/pdf [tmp_name] => C:\Users\HogRider\xampp\tmp\phpE786.tmp [error] => 0 [size] => 500624 ) )

table

table

2 个答案:

答案 0 :(得分:3)

根据PHP/PDO/MySQL: inserting into MEDIUMBLOB stores bad data,尝试使用以下行构建您的PDO对象:

$dbh = new PDO($dsn, $username, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1 COLLATE latin1_general_ci"));

<强>解释

我认为正如Ben M在相关问题中所指出的那样,有两个糟糕的设计决策在这里工作。

这是连接字符集的概念。这个想法是SQL文本可以在任何字符集中,然后在SQL服务器检索时进行转换。

这对于二进制数据来说效果不好,因为它不是文本,因此,根据定义,它不能位于任何字符集中,但仍然使用字符串文字传输

通过在传输期间引用BLOB数据(使用BASE64_ *函数或hex-escaping)可以解决此问题,实际上,这正是许多人正在做的事情。

第二个设计决策是在PDO / PHP中:PDO不进行任何字符集转换(它不能,因为PHP中的字符串本质上是字符集不可知的)因此PHP是唯一(或少数几种语言之一) SQL传输字符集的选择实际上很重要,因为它需要匹配输入字符串实际所在的编码。

在其他语言中,传输字符集只需要表达足以包含可能在字符串中使用的任何字符。在今天的表情符号世界中,这很可能只能通过unicode字符集(utf-8等)来保证。但是,这些都不是二进制安全的(因为并非每个可能的字节组合都会生成一个有效的字符串)所以即使我们可以解决PHP问题,我们仍然会遇到问题# 1。

在理想情况下,SQL命令在传输过程中始终位于ASCII字符集中,并且每个字符串值都有一个charset参数,其中“binary”可能是一个可能的值,随之提供。 MySQL实际上有一个字符串构造,它称之为“介绍人”。但是,“_ binary”似乎不是一个有效的值。

然后,另一端将使用此字符集信息将字符串值转换为其本机字符集(用于客户端到服务器传输的列或用于服务器到客户端传输的编程语言的字符串字符集)。

这样,唯一需要在BLOB值中转义的就是字符串分隔符("')。

答案 1 :(得分:1)

你可以尝试

的MySQL

CREATE TABLE files (
    id   INT           AUTO_INCREMENT PRIMARY KEY,
    mime VARCHAR (255) NOT NULL,
    data BLOB          NOT NULL
);

PHP

  class BlobDemo {

        const DB_HOST = 'localhost';
        const DB_NAME = 'nameofdb';
        const DB_USER = 'username';
        const DB_PASSWORD = 'password';

        /**
         * PDO instance
         * @var PDO 
         */
        private $pdo = null;

        /**
         * Open the database connection
         */
        public function __construct() {
            // open database connection
            $conStr = sprintf("mysql:host=%s;dbname=%s;charset=utf8", self::DB_HOST, self::DB_NAME);

            try {
                $this->pdo = new PDO($conStr, self::DB_USER, self::DB_PASSWORD);
                //for prior PHP 5.3.6
                //$conn->exec("set names utf8");
            } catch (PDOException $e) {
                echo $e->getMessage();
            }
        }

        /**
         * insert blob into the files table
         * @param string $filePath
         * @param string $mime mimetype
         * @return bool
         */
        public function insertBlob($filePath, $mime) {
            $blob = fopen($filePath, 'rb');

            $sql = "INSERT INTO files(mime,data) VALUES(:mime,:data)";
            $stmt = $this->pdo->prepare($sql);

            $stmt->bindParam(':mime', $mime);
            $stmt->bindParam(':data', $blob, PDO::PARAM_LOB);

            return $stmt->execute();
        }
}

$blobObj = new BlobDemo();

// test insert pdf
$blobObj->insertBlob('pdf/prova.pdf',"application/pdf");

为我工作,我尝试使用PDF,JPG和HTML进行插入更新和查看。