【发布时间】:2015-09-11 23:42:25
【问题描述】:
我正在使用 CGI::Session 将 utf-8 会话数据存储到 MySQL DB 中,并使用 YAML 作为序列化程序,效果很好。问题是在解冻时,会话数据似乎没有被解码为 Perls 内部格式,尽管传递给会话构造函数的数据库句柄被配置为这样做。 解冻后立即在每个会话参数上手动应用 decode_utf8 确实可以解决此问题,但这很不方便。
这是我的设置:
use warnings;
use strict;
$dbh->{'mysql_enable_utf8'} = 1;
$dbh->do('set names utf8');
$session = CGI::Session->new("driver:MySQL;serializer:yaml", undef, {
TableName => "session",
IdColName => "id",
DataColName => "data",
Handle => $dbh,
} ) or die CGI::Session->errstr;
# column 'data' of table 'session' is of type mediumtext, has charset utf8 and collation utf8_unicode_ci
示例 sn-p:
binmode(STDIN, ":encoding(utf8)");
binmode(STDOUT, ":encoding(utf8)");
if( !defined $session->param('first_name') ){
$session->param('first_name','jörg');
}
print $session->param('first_name');
第一次运行时会输出:'jörg'
在第二次运行时(名称现在来自会话表):'jörg'
如上所述,这将解决它:
binmode(STDIN, ":encoding(utf8)");
binmode(STDOUT, ":encoding(utf8)");
if( !defined $session->param('first_name') ){
$session->param('first_name','jörg');
} else {
$session->param('first_name',decode_utf8($session->param('first_name')));
}
print $session->param('first_name');
(我确实使用完全相同的数据库句柄将“first_name”存储在“person”表中,并且从那里读取/写入/输出可以完美运行。)
那么,为什么数据不能通过 CGI::Session 正确解码为 Perls 格式,或者我如何告诉 CGI::Session 这样做呢? 此行为还会导致序列化程序 Dumper、Storable 和 FreezeThaw 在尝试解冻之前已损坏的数据时崩溃。 例如。当会话数据不是 Perls 内部格式时,Dumper 只会在 'jörg' 的 'ö' 处剪切会话数据。
非常感谢您对此提供的任何提示,请原谅我用词不当。我只是想弄清楚 unicode-in-perl 问题。 (是的,我已经阅读了许多通用指南和操作方法,但遗憾的是找不到关于 session-mysql 主题的任何内容。)
最好的问候, 托马斯
根据simbaque更新(感谢提示),但确实不是这里的问题。
【问题讨论】:
-
您的代码在示例
new CGI::Session中看起来有点过时。你应该添加use strict和use warnings虽然我不认为这是这里的问题。