PHP使用iconv将泰语ISO-IR-166编码转UTF-8失效问题咨询
问题根因
两个异常表现的核心原因都是传入iconv的输入字符串实际编码和你声明的第一个参数ISO-IR-166不匹配。你代码里写的字符字面量'¤'、'Á'实际编码是你当前PHP源文件的编码(大概率是UTF-8),而UTF-8下这两个字符都是多字节编码,你强制告诉iconv这是单字节的ISO-IR-166编码内容,自然会出现解析错误。
第一个问题:¤转换后返回ยค的原因
UTF-8编码下,¤对应的字节序列是0xC2 0xA4,你声明输入是ISO-IR-166(单字节泰语编码),iconv会把这两个字节当成两个独立的ISO-IR-166字符解析:
0xC2在ISO-IR-166码表中对应字符ย0xA4在ISO-IR-166码表中对应字符ค
拼接后就是你得到的ยค,和预期不符是因为你实际传入的不是ISO-IR-166编码下代表ค的单字节0xA4。
第二个问题:Á转换返回false的原因
UTF-8编码下,Á对应的字节序列是0xC3 0x81,其中0x81不属于ISO-IR-166的有效编码范围,iconv遇到无法识别的编码字符时默认就会返回false。你预期的ม对应的是ISO-IR-166编码下的单字节0xE1,和你传入的UTF-8的Á完全不是同一个字节内容。
解决方法
- 确保输入字符串编码和声明一致:如果要测试ISO-IR-166指定码值的转换,不要直接写UTF-8的字符字面量,用
chr()函数生成对应单字节的输入:// 转换ISO-IR-166的0xA4到UTF-8,输出ค $convertedChar = iconv('ISO-IR-166', "UTF-8", chr(0xA4)); // 转换ISO-IR-166的0xE1到UTF-8,输出ม $convertedChar = iconv('ISO-IR-166', "UTF-8", chr(0xE1)); - 兼容异常字符处理:如果转换时可能遇到无效编码,可以给输出编码增加
//IGNORE或者//TRANSLIT后缀,避免直接返回false:// 遇到无效字符自动忽略,继续转换后续内容 $convertedChar = iconv('ISO-IR-166', "UTF-8//IGNORE", $input); // 遇到无法直接转换的字符尝试用相似字符替代 $convertedChar = iconv('ISO-IR-166', "UTF-8//TRANSLIT", $input); - 编码别名兼容:部分环境的iconv库对
ISO-IR-166的支持可能不友好,可以替换为等价的别名TIS-620使用,效果完全一致。
内容的提问来源于stack exchange,提问作者Marsa Baniasadi
相关产品推荐
相关产品推荐

