iconv 字符编码转换
PHP 的 iconv 扩展提供了字符编码之间的转换功能。在处理多语言数据时,字符编码转换是必不可少的操作。iconv 支持几乎所有常见的字符编码格式,包括 UTF-8、GBK、BIG5、ISO-8859-1、Shift-JIS 等。
基础概念
安装
bash
# 编译安装
./configure --with-iconv
# Ubuntu/Debian
sudo apt-get install php-iconv
# 检查可用编码
echo iconv -l | head -20iconv 函数
基本转换
php
<?php
declare(strict_types=1);
// GBK 转 UTF-8
$utf8 = iconv('GBK', 'UTF-8', '中文内容');
echo $utf8 . PHP_EOL;
// UTF-8 转 GBK
$gbk = iconv('UTF-8', 'GBK', '中文内容');
echo $gbk . PHP_EOL;
// UTF-8 转 ISO-8859-1
$iso = iconv('UTF-8', 'ISO-8859-1//IGNORE', 'Hello 世界');
// //IGNORE 忽略无法转换的字符
// BIG5 转 UTF-8
$utf8 = iconv('BIG5', 'UTF-8', $big5String);错误处理选项
php
<?php
declare(strict_types=1);
// 输出编码后缀选项:
// //IGNORE - 忽略无法转换的字符
// //TRANSLIT - 将无法转换的字符用近似字符替代
// 忽略无法转换的字符
$result = iconv('UTF-8', 'ISO-8859-1//IGNORE', 'Hello 世界');
echo $result . PHP_EOL; // Hello
// 音译替代
$result = iconv('UTF-8', 'ASCII//TRANSLIT', 'cafe résumé');
echo $result . PHP_EOL; // cafe resume
// 同时使用
$result = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', 'cafe résumé 世界');
echo $result . PHP_EOL;获取编码信息
php
<?php
declare(strict_types=1);
// 检测字符串编码
$encoding = mb_detect_encoding($string, ['UTF-8', 'GBK', 'BIG5', 'ISO-8859-1'], true);
echo "检测到的编码: {$encoding}" . PHP_EOL;
// iconv 获取支持的编码列表
// $encodings = iconv_get_encoding('all');实战示例
文件编码转换
php
<?php
declare(strict_types=1);
/**
* 将文件从一种编码转换为另一种
*/
function convertFileEncoding(
string $inputPath,
string $outputPath,
string $fromEncoding,
string $toEncoding
): void {
$content = file_get_contents($inputPath);
$converted = iconv($fromEncoding, $toEncoding . '//IGNORE', $content);
file_put_contents($outputPath, $converted);
}
// GBK 文件转 UTF-8
convertFileEncoding('/path/to/gbk-file.txt', '/path/to/utf8-file.txt', 'GBK', 'UTF-8');批量文件编码检测与转换
php
<?php
declare(strict_types=1);
class EncodingConverter
{
private string $targetEncoding;
public function __construct(string $targetEncoding = 'UTF-8')
{
$this->targetEncoding = $targetEncoding;
}
/**
* 检测并转换字符串编码
*/
public function convert(string $content, ?string $fromEncoding = null): string
{
if ($fromEncoding === null) {
$fromEncoding = mb_detect_encoding($content, ['UTF-8', 'GBK', 'BIG5', 'ISO-8859-1'], true);
}
if ($fromEncoding === $this->targetEncoding) {
return $content;
}
$result = @iconv($fromEncoding, $this->targetEncoding . '//IGNORE', $content);
return $result !== false ? $result : $content;
}
/**
* 转换目录下所有文件
*/
public function convertDir(string $dir, array $extensions = ['txt', 'php', 'html']): void
{
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
$ext = $file->getExtension();
if (!in_array($ext, $extensions)) {
continue;
}
$content = file_get_contents($file->getPathname());
$converted = $this->convert($content);
if ($converted !== $content) {
file_put_contents($file->getPathname(), $converted);
echo "已转换: {$file->getPathname()}" . PHP_EOL;
}
}
}
}注意事项
iconv()在转换失败时返回false- 使用
//IGNORE或//TRANSLIT处理无法转换的字符 - PHP 8.2+ 中 iconv 扩展始终可用
下一节
继续学习:Gettext 本地化