重新连接时,MDB2断开连接并忘记字符集设置

时间:2021-02-18 07:13:18

We recently debugged a strange bug. A solution was found, but the solution is not entirely satisfactory.

我们最近调试了一个奇怪的bug。找到了解决方案,但解决方案并不完全令人满意。

We use IntSmarty to localize our website, and store the localized strings in a database using our own wrapper. In its destructor, IntSmarty saves any new strings that it might have, resulting in a database call.

我们使用IntSmarty本地化我们的网站,并使用我们自己的包装器将本地化的字符串存储在数据库中。在其析构函数中,IntSmarty会保存它可能具有的任何新字符串,从而导致数据库调用。

We use a Singleton instance of MDB2 to do queries against MySQL, and after connecting we used the SetCharset()-function to change the character set to UTF-8. We found that strings that were saved by IntSmarty were interpreted as ISO-8859-1 when the final inserts were made. We looked closely at the query log, and found that the MySQL connection got disconnected before IntSmarty's destructor got called. It then got reestablished, but no "SET NAMES utf8" query was issued on the new connection. This resulted that the saved strings got interpreted as ISO-8859-1 by MySQL.

我们使用SingleB2的MDB2实例对MySQL进行查询,连接后我们使用SetCharset()函数将字符集更改为UTF-8。我们发现在最终插入时,IntSmarty保存的字符串被解释为ISO-8859-1。我们仔细查看了查询日志,发现在IntSmarty的析构函数被调用之前,MySQL连接断开了。然后重新建立,但在新连接上没有发出“SET NAMES utf8”查询。这导致MySQL保存的字符串被解释为ISO-8859-1。

There seems to be no options that set the default character set on MDB2. Our solution to this problem was changing the MySQL server configuration, by adding

似乎没有选项在MDB2上设置默认字符集。我们解决这个问题的方法是通过添加更改MySQL服务器配置

init-connect='SET NAMES utf8'

to my.cnf. This only solves the problem that our character set is always the same.

到my.cnf。这只解决了我们的字符集始终相同的问题。

So, is there any way that I can prevent the connection from being torn down before all the queries have been run? Can I force the MDB2 instance to be destructed after everything else?

那么,有没有什么办法可以防止连接在所有查询运行之前被拆除?在其他所有事情之后我可以强制MDB2实例被破坏吗?

Turning on persistent connections works, but is not a desired answer.

打开持久连接有效,但不是理想的答案。

1 个解决方案

#1


1  

From the PHP5 documentation:

从PHP5文档:

The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence.

一旦删除了对特定对象的所有引用,或者在关闭序列中显式销毁对象或以任何顺序,就会调用析构函数方法。

PHP documentation

(emphasis mine)

What is probably happening is that your script does not explicitly destroy the object, and so when PHP gets to the end of the script it starts cleaning up things in whatever order it feels like--which in your case, is closing the database link first.

可能发生的事情是你的脚本没有明确地销毁对象,所以当PHP到达脚本的末尾时,它开始以任何顺序清理东西 - 在你的情况下,它首先关闭数据库链接。

If you explicitly destroy the IntSmarty object prior to the actual end of the script, that should solve your problem.

如果在脚本实际结束之前显式销毁IntSmarty对象,那么这应该可以解决您的问题。

#1


1  

From the PHP5 documentation:

从PHP5文档:

The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence.

一旦删除了对特定对象的所有引用,或者在关闭序列中显式销毁对象或以任何顺序,就会调用析构函数方法。

PHP documentation

(emphasis mine)

What is probably happening is that your script does not explicitly destroy the object, and so when PHP gets to the end of the script it starts cleaning up things in whatever order it feels like--which in your case, is closing the database link first.

可能发生的事情是你的脚本没有明确地销毁对象,所以当PHP到达脚本的末尾时,它开始以任何顺序清理东西 - 在你的情况下,它首先关闭数据库链接。

If you explicitly destroy the IntSmarty object prior to the actual end of the script, that should solve your problem.

如果在脚本实际结束之前显式销毁IntSmarty对象,那么这应该可以解决您的问题。