使用php通过odbc检索DB2值时出现字符集问题

使用php通过odbc检索DB2值时出现字符集问题,php,db2,odbc,Php,Db2,Odbc,我试图通过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

我试图通过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”。如果我把代码放在我的浏览器上,我会得到一个单词fine,但是当它被写入文件时,它会在上面出现奇怪的字符(这就是为什么我认为字符集有问题的原因)。我尝试过不同的解决办法,但这只会让事情变得更糟。使用Notepad++(启用UTF8编码)打开的文件如下所示:

PHP中是否有在字符集之间进行转换的函数

编辑

按照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上执行命令locale,我会得到:

LC_NAME="es_ES.UTF-8"
LC_ADDRESS="es_ES.UTF-8"
...

我将尝试从评论中总结出一个答案:

首先请注意,PHPs
utf8_encode
将从
ISO-8859-1
转换为
utf-8
。如果数据库/ODBC驱动程序未返回
ISO-8859-1
encoded字符串,PHPs
utf8\u encode
将失败或返回垃圾

最简单的解决方案应该是让数据库/驱动程序使用其
CAST
功能将值转换为正确的编码:

尝试更改查询,让DB2直接将所有内容转换为UTF-8,并省略
utf8\u 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..

数据库中对应的字段是什么类型?存储在该字段中的数据的编码是什么?如果您在浏览器中使用var_dump,浏览器使用什么编码来正确显示数据?字段的类型它是字母数字类型。数据库使用的编码是EBCDIC。当我在浏览器上打印代码时,我没有在代码上添加任何标记。如果按F10显示菜单,然后选择“查看”->“编码”(Firefox),浏览器会怎么说?还要检查php认为
$paraula
编码的内容,检查
mb\u detect\u编码($paraula)
。它说它是用Unicode编码的(执行您提到的Firefox“View”->“Encoding”时)会向我抛出一个obdc_prepare()错误,表示符号UNICODE无效。错误是用西班牙语抛出的,错误中缺少字母(因为系统甚至无法获得正确的字符集)我如何为驱动程序分配正确的编码?还有其他解决方法吗?我仍然停留在这个问题上。您的方法可以改变一点查询:SELECT CAST(名称为VARCHAR(255)CCSID 1208)…1208相当于使用IBM PUA的UTF-8。它不适用于UNICODE station。