当前位置: 首页 > 面试题库 >

PHP / PDO / MySQL:插入MEDIUMBLOB会存储错误数据

巫马淳
2023-03-14
问题内容

我有一个简单的PHP Web应用程序,该应用程序通过文件上传接受图标图像并将其存储在MEDIUMBLOB列中。

在我的计算机(Windows)和两个Linux服务器上,这可以正常工作。在第三台Linux服务器上,插入的映像已损坏:执行SELECT后不可读,并且MySQL
length()函数报告的列数据长度比上载文件的大小大40%。

(每个服务器都连接到一个单独的MySQL实例。)

当然,这使我考虑了编码和字符集问题。BLOB列没有关联的字符集,因此似乎最可能的罪魁祸首是PDO及其对该列的参数值的解释。

  • 我尝试将bindValue与PDO :: PARAM_LOB结合使用,没有任何效果。
  • 我已经验证了图像在服务器上的正确接收(即正在上传后毫无问题地读取它们),因此,这肯定是DB / PDO问题。
  • 我一直在寻找服务器之间明显的配置差​​异,但是我不是PHP配置方面的专家,因此我可能会错过一些东西。

插入代码大致如下:

$imagedata = file_get_contents($_FILES["icon"]["tmp_name"]);
$stmt = $pdo->prepare('insert into foo (theimage) values (:theimage)');
$stmt->bindValue(':theimage', $imagedata, PDO::PARAM_LOB);
$stmt->execute();

任何帮助将不胜感激。

更新 :有问题的服务器上的默认MySQL字符集是utf8;在其他人身上是拉丁的。

通过添加PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1 COLLATE latin1_general_ci"到PDO构造函数可以“解决”问题。

在我看来,这似乎是 个错误的 设计:为什么 连接
的字符集对二进制列的数据有任何影响,特别是当使用PARAM_LOB将其识别为PDO本身的二进制数据时?

请注意,在所有情况下,数据库表都定义为latin1:只有服务器的默认字符集不一致。


问题答案:

在我看来,这似乎是个错误:为什么连接的字符集对二进制列的数据有任何影响,特别是当使用PARAM_LOB将其标识为PDO本身为二进制时?

我认为这一定不是错误。我可以想象,每当客户端与服务器对话并说以下命令位于UTF-8中,而服务器需要使用Latin-1时,则查询可能会在解析和执行之前得到重新编码。因此,这是数据传输的编码问题。由于整个查询之前的解析将受到此重新编码的影响,因此BLOB列的二进制数据也将发生变化。

从Mysql手册中:

服务器在收到语句后应将其转换为什么字符集?

为此,服务器使用character_set_connection和collat​​ion_connection系统变量。它将客户端发送的语句从character_set_client转换为character_set_connection(具有诸如_latin1或_utf8之类的介绍符的字符串文字除外)。collat​​ion_connection对于比较文字字符串很重要。对于将字符串与列值进行比较,collat​​ion_connection无关紧要,因为列具有自己的排序规则,排序规则优先级更高。

或在返回途中:来自商店的Latin1数据将转换为UTF-8,因为客户端告诉服务器它更喜欢使用UTF-8进行运输。

您命名的PDO本身的标识符看起来完全不同:

PDO :: PARAM_LOB 告诉PDO将数据映射为流,以便您可以使用PHP Streams
API对其进行操作。(参考)

我不是MySQL专家,但是我会这样解释。客户端和服务器需要协商使用的是哪些字符集,我认为他们这样做是有原因的。



 类似资料:
  • 本文向大家介绍PHP PDO将数据插入表,包括了PHP PDO将数据插入表的使用技巧和注意事项,需要的朋友参考一下 插入数据非常简单,因为我们已经知道如何使用PDO与mysql(MariaDB)建立连接?我们可以使用与框架相同的代码,然后编辑$sql查询以插入数据而不是选择数据。 PHP代码使用PDO将数据插入表 输出结果 这样,我们可以使用PDO与MySQL进行交互,以轻松地向数据库表中添加新记

  • 赫杰。 我在执行我的代码时会收到这个错误信息?我在表单中发布值“2020-12-19”。我不知道1989年是从哪里来的... 消息: 代码: 最好的问候/Svante

  • 主要内容:使用 MySQLi 和 PDO 向 MySQL 插入数据,实例 (MySQLi - 面向对象),实例 (MySQLi - 面向过程),实例 (PDO)使用 MySQLi 和 PDO 向 MySQL 插入数据 在创建完数据库和表后,我们可以向表中添加数据。 以下为一些语法规则: PHP 中 SQL 查询语句必须使用引号 在 SQL 查询语句中的字符串值必须加引号 数值的值不需要引号 NULL 值不需要引号 INSERT INTO 语句通常用于向 MySQL 表添加新的记录: 学习更多关于

  • 问题内容: SQL查询: MySQL说: 即使在行1062处没有条目,它也会显示此重复的条目错误。(ID是主键,并且是unique(ID_Category,Keyword))。你能帮我吗?… 问题答案: 您的数据库中已经有一行带有值“ 18”和“免费邮件”的行。由于存在唯一性约束,因此不能有两个这样的行。您有一些选择: 删除原始行,然后再次尝试插入:。 删除唯一性约束以允许两行同时存在。 使用忽略

  • 问题内容: 插入数据库时​​出现错误。 代码: 忽略dbquery,与mysql_query完全一样。 我收到的错误是: 不知道为什么会引发此错误! 问题答案: 教一个人如何钓鱼。 如果查询失败,那么您应该做的第一件事就是回显您要发送的查询: 通常,最终查询到底出了什么问题,这是很明显的。要特别注意查询中的动态内容,通常要注意MySQL抱怨的区域。 如果看起来还可以,那么您会寻找可能需要转义的单词

  • 问题内容: 我有这样的数组 当我做一个var-dump时我得到这个-> 现在,我尝试使用IN语句将此添加到数据库中- 我遇到的问题是内爆返回一个字符串。但是“ phone”列是数据库中的整数,并且数组也将其存储为整数。因此,由于我的最终查询如下所示,因此出现了SQL错误- 这是一个错误的查询。有没有解决的办法。 我的列名是动态的,基于用户要插入的内容。所以我不能使用诸如 :phone 和 :ima