首页 \ 问答 \ PHP / PDO / MySQL:插入MEDIUMBLOB存储坏数据(PHP/PDO/MySQL: inserting into MEDIUMBLOB stores bad data)

PHP / PDO / MySQL:插入MEDIUMBLOB存储坏数据(PHP/PDO/MySQL: inserting into MEDIUMBLOB stores bad data)

我有一个简单的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本身的二进制时?

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


I have a simple PHP web app that accepts icon images via file upload and stores them in a MEDIUMBLOB column.

On my machine (Windows) plus two Linux servers, this works fine. On a third Linux server, the inserted image is corrupted: unreadable after a SELECT, and the length of the column data as reported by the MySQL length() function is about 40% larger than the size of the uploaded file.

(Each server connects to a separate instance of MySQL.)

Of course, this leads me to think about encoding and character set issues. BLOB columns have no associated charsets, so it seems like the most likely culprit is PDO and its interpretation of the parameter value for that column.

  • I've tried using bindValue with PDO::PARAM_LOB, to no effect.
  • I've verified that the images are being received on the server correctly (i.e. am reading them post-upload with no problem), so it's definitely a DB/PDO issue.
  • I've searched for obvious configuration differences between the servers, but I'm not an expert in PHP configuration so I might have missed something.

The insert code is pretty much as follows:

$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();

Any help will be really appreciated.

UPDATE: The default MySQL charset on the problematic server is utf8; it's latin1 on the others.

The problem is "solved" by adding PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1 COLLATE latin1_general_ci" to the PDO constructor.

This seems like a bug poor design to me: why should the charset of the connection have any effect on data for a binary column, particularly when it's been identified as binary to PDO itself with PARAM_LOB?

Note that the DB tables are defined as latin1 in all cases: it's only the servers' default charsets that are inconsistent.


原文:https://stackoverflow.com/questions/6346319
更新时间:2024-01-25 21:01

最满意答案

您可以将gridview元素的IsTabStop属性更改为false以获得该效果。

此外,如果您想使用Tab循环,可以使用TabNavigation="Cycle"

这两个变化都在xaml中。


You can change your gridview element's IsTabStop property to false to gain that effect.

Also if you want to cycle with Tab you can TabNavigation="Cycle" .

Both changes are in xaml.

相关问答

更多
  • 使用TextChanged事件。 的.xaml: .xaml.cs: private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { string text = ((TextBox)sender).Text; // call your function } Use the TextChanged event ...
  • 如果将wpf窗口集成到win-forms-application中,我已经看到过这样的行为。 如果是这样,请发表评论。 如果没有,请检查您是否在父元素(窗口,用户控件,网格)中注册了一个PreviewKeyDown事件处理程序,该处理程序将e.Handled属性设置为true(或任何其他处理键盘的注册预览事件处理程序 - 输入)。 因为您编写了复制粘贴和空间工作,我假设您没有在父元素或父元素的样式或控件模板或隐式样式中设置TextBox.IsReadOnly。 还有一件事:是线
  • 看起来你必须通过HeaderRow来访问它 CheckBox chkCaseSearch = gvFirearms.HeaderRow.FindControl(“chkCaseSearch”)作为CheckBox; Looks like you have to access it through the HeaderRow like so CheckBox chkCaseSearch = gvFirearms.HeaderRow.FindControl("chkCaseSearch") as CheckBo ...
  • 将更新面板的更新模式属性设置为“始终”。 在TextBox1_TextChanged事件下的代码隐藏文件中,您可以使用sender.text属性获取最新值。 如果将updateMode设置为conditional,则需要添加触发器。 ---------------------这是我试过的代码及其工作原理------------------ <%@ Page Title="Abo ...
  • 您可以将gridview元素的IsTabStop属性更改为false以获得该效果。 此外,如果您想使用Tab循环,可以使用TabNavigation="Cycle" 。 这两个变化都在xaml中。 You can change your gridview element's IsTabStop property to false to gain that effect. Also if you want to cycle with Tab you can TabNavigation="Cycle" . Bo ...
  • 单击“更新”后,将引发两个事件。 1.)GridView.Updating:在即将提交更新之前引发。 在这种情况下,数据仍未在数据库中更新。 基本上,此事件用于在Update方法实际将更改的数据提交到数据库之前根据需要应用某些动态更改。 2.)GridView.Updated数据更新后立即引发此事件。 因此,仅在此事件中,您只需输入调试符号并检查值。 你会看到你的新价值:斯科特。
    只需使用以下示例 Just use following example
  • 您需要将Page_Load代码更新为: If Not IsPostBack Then GridView1.DataSource = f.xDa GridView1.DataBind() End If 当您的代码到达Button_Click事件时,它已经使用数据库中的数据重新填充GridView(覆盖用户键入TextBox的内容)。 我上面添加的代码导致数据仅在第一次加载 - 然后ASP.NET视图状态处理确保GridView的状态保持最新。 You need to update your ...
  • 试试这个 : private void ReadWriteTB_TextChanged(object sender, RoutedEventArgs e) { txtInputID.Attributes.Add("onfocus", "javascript:this.value=this.value;") txtInputID.Focus() }