PHP8.0与PHP8.1中iconv长dash转义行为差异排查
PHP 8.1中iconv无法将长dash转写为减号的问题解决
问题现象
- PHP 8.1环境下,执行
iconv('UTF-8', 'ASCII//TRANSLIT', '–')转换长dash("–")时,抛出错误:iconv(): Detected an illegal character in input string - 相同代码在PHP 8.0中可正常输出减号("-")
- 环境细节:
- 两个PHP版本均依赖glibc 2.27
- PHP配置仅
log_errors_max_len参数有差异 - Ubuntu 18.04升级至PHP 8.0.29/8.1.20后问题仍存在,但Ubuntu 22.04的sury包环境无此问题
复现步骤
$ cat iconv.php <?php phpinfo(); echo iconv('UTF-8', 'ASCII//TRANSLIT', '–'); $ php8.0 iconv.php > /tmp/8.0.out 2>&1 $ php8.1 iconv.php > /tmp/8.1.out 2>&1 $ diff /tmp/8.0.out /tmp/8.1.out # 省略diff输出内容
可能原因
PHP 8.1调整了iconv的错误处理逻辑,或者同版本glibc的translit规则在不同PHP编译环境下的应用存在差异。Ubuntu 22.04的sury包可能集成了更新的字符转写补丁,或编译参数优化了translit规则的识别范围。
解决方案
方案1:手动替换特殊dash字符
在调用iconv前提前替换长dash(en dash)和长破折号(em dash)为普通减号,不依赖translit规则:
$str = '–'; // 覆盖常见的特殊dash类型 $str = str_replace(['–', '—'], '-', $str); echo iconv('UTF-8', 'ASCII//TRANSLIT', $str);
方案2:用strtr自定义字符映射
直接通过字符串映射处理特殊字符,避免iconv的translit依赖:
$str = '–'; $charMap = [ '–' => '-', '—' => '-', // 可添加其他需要转写的特殊字符 ]; echo strtr($str, $charMap);
方案3:升级系统或更换PHP源
若业务允许,升级至Ubuntu 22.04并使用sury提供的PHP包,该环境下已修复此问题。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

