【问题标题】:Why is my blob reading as an array?为什么我的 blob 读取为数组?
【发布时间】:2017-11-01 22:26:11
【问题描述】:

我有一个 HTML5 录音机,它产生一个音频 blob(Matt Diamond 的 recorder.js)并对我的 PHP 文件执行 jquery ajax 调用。

function audioUpload() {

    recorder && recorder.exportWAV(function(blob) {
        //first look at the blob
        console.log(blob);

        var fd = new FormData();
        fd.append('audioBlob', blob);
        var audioBlob = fd.get('audioBlob');

        //second look at the blob
        console.log(audioBlob);

        $.ajax({
            method: "POST",
            data: fd,
            contentType: false,
            processData: false,
            url: "audioSend.php",
        }).done(function(data) {
            console.log(data);
          })
    });

这里有两个 console.log 函数可以报告 blob:

首先,控制台读取为 blob。 1 在代码的另一部分中,我使用它创建了一个对象 URL,并且可以使用 HTML5 音频标签播放音频,所以它正在工作。

在第二个中,控制台将其作为文件读取。 2 我可以理解这一点,因为按照定义,blob 是类似文件的对象。不过,我不确定为什么它不像第一个实例那样被报告为 blob。

formData 对象被发布到 audioSend.php 中,我在其中获取值并将其插入到我的数据库中。

$audioBlob = $_FILES['audioBlob'];

$results = mysqli_query($connection, "INSERT INTO audioLog (audio) VALUES ('$audioBlob')");

echo ($audioBlob);

尝试将 blob 值插入我的数据库会引发“数组到字符串转换”错误,并且回显 $audioBlob 确认它被读取为数组。结果,我的 MYSQL DB Blob 列中显示的值只有几个字节,而不是我想要的更大的音频 blob 对象。

为什么将 blob 读取为数组,如何将 REAL blob 值插入到我的数据库中?

【问题讨论】:

  • 仅供参考 - 当您将来遇到此类问题时,print_r() 是您的朋友。
  • print_r() 永远不是你的朋友,但var_dump() 是。 :P
  • @Sammitch var_dump() 也确认了 $audioBlob 的值是一个数组,正如我在 echo() 中看到的那样。

标签: php ajax audio mysqli blob


【解决方案1】:

您正在发布数据,因此请通过 $_POST 访问它:

$audioBlob = $_POST['audioBlob'];

此外,请使用准备好的语句,因为您容易受到 SQL 注入的攻击。

【讨论】:

  • +1 表示准备好的语句。需要注意的是,特别大的 blob 可能需要特别考虑存储和检索,例如:php.net/manual/en/mysqli-stmt.send-long-data.php 或者,将 blob 数据放入文件并将该文件的路径存储在数据库中。
  • 我在使用 $_POST 时根本没有得到任何值 (null)。我见过的上传对象的工作建议使用 $_FILES 代替。就像我说的那样,它在那里,但它被读取为数组而不是对象。 @Sammitch 目前我上传的 blob 不超过 300 KB,但稍后会考虑大小。如果我不能很快解决这个问题,我可能会走文件服务器路线。
【解决方案2】:

再次查看您的代码,虽然我不是 JS 程序员,但您似乎禁用了任何优雅的 POST 并且只是将原始数据塞进了 POST 请求中。

如果您想获取这些数据,您必须打开包含未处理的 POST 正文的 php://input 流。例如:

$f_in = fopen('php://input', 'rb');
$f_out = fopen($APPROOT.'/files/foo.bin', 'wb');
while( ! feof($f_in) ) {
    $buf = fread($f_in, 4096);
    fwrite($f_out, $buf);
}
fclose($f_in);
fclose($f_out);

这会将 POST 数据一次写入文件$APPROOT.'/files/foo.bin' 4KB,而不会先将整个内容塞入内存。

如果您想将其作为文件上传并在$_FILES 中提供,您必须研究如何通过任何 JS 库正确上传文件。

【讨论】:

  • 不幸的是,我使用的代码是在我使用的 JS 库 Jquery 中上传文件的推荐方法。谢谢你的帮助。我会查看输入流,看看那里有没有东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 2023-02-06
  • 2013-05-04
  • 1970-01-01
  • 1970-01-01
  • 2020-06-22
相关资源
最近更新 更多