我正在尝试通过PHP和odbc从DB2中进行选择,然后将这些值保存在文件中。正在执行代码的操作系统是Debian。我的工作如下:
$query = "SELECT NAME FROM DATABASE_EXAMPLE.TABLE_EXAMPLE";
$result = odbc_prepare($server, $query);
$success = odbc_execute($result);
$linias = "";
if ($success) {
while ($myRow = odbc_fetch_array($result)) {
$linias .=format_word($myRow['NAME'], 30) . "\r\n";
}
generate_file($linias);
function format_word($paraula, $longitut) {
return str_pad(utf8_encode($paraula), $longitut, " ", STR_PAD_LEFT);
}
function generate_file($linias) {
$nom_fitxer = date('YmdGis');
file_put_contents($nom_fitxer . ".tmp", $linias);
rename($nom_fitxer . '.tmp', $nom_fitxer . '.itf');
}
问题是某些检索到的值包含西班牙语字母和重音符号。举例来说,其中一个值是“ÁNGULO”。如果我在我的浏览器上var_dump代码我得到了一个好的单词,但是当它写入文件时,它会在它上面添加奇怪的字符(这就是为什么我认为charset存在问题)。我尝试了不同的解决方法,但它只是让它变得更糟。使用Notepad ++(启用了UTF8编码)打开的文件如下所示:
PHP中是否有一个在charsets之间进行转换的函数?
修改
按照erg说明,我做了进一步的研究:
DB2数据库使用IBM284字符集,因为我发现执行下一个命令:
select table_schema, table_name, column_name, character_set_name from SYSIBM.COLUMNS
Firefox称该页面编码为Unicode。 如果我这样做:
var_dump(mb_detect_encoding($paraula));
结果我得到了布尔(假)。
我已经改变了我的功能,以形成希望iconv解决冲突的词:
function format_word($paraula, $longitut) {
$paraula : mb_convert_encoding($paraula, 'UTF-8');
$paraula= iconv("IBM284", "UTF-8", $paraula);
return $paraula;
}
但事实并非如此。看起来像ODBC它正在做一些编纂不好,这就是混乱的数据。如何修改odbc以修改到正确的字符集?我在Linux上看到一些改变语言环境的东西,但如果我在PC上执行命令语言环境,我得到:
LC_NAME="es_ES.UTF-8"
LC_ADDRESS="es_ES.UTF-8"
...
答案 0 :(得分:1)
我将尝试从评论中总结出答案:
首先请注意,PHP utf8_encode
将从ISO-8859-1
转换为utf-8
。如果您的数据库/ ODBC驱动程序未返回ISO-8859-1
编码的字符串,则PHP utf8_encode
将失败或返回垃圾。
最简单的解决方案应该是让数据库/驱动程序使用CAST
函数将值转换为正确的编码:https://www.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/sqlref/src/tpc/db2z_castspecification.html
尝试更改您的查询,让DB2直接将所有内容转换为UTF-8,并省略utf8_encode
调用。这可以通过将查询更改为:
SELECT CAST(NAME AS VARCHAR(255) CCSID 1208) FROM DATABASE_EXAMPLE.TABLE_EXAMPLE
感谢Sergei关于IBM PUA的CCSID 1208
的说明。我将CCSID UNICODE
更改为CCSID 1208
。
我这里没有DB2,所以上面的查询是未经测试的。我不确定这是否会返回utf-8或utf-16 ..