字符编码错误
Character wrongly encoded
我有文件名中包含字符 ⌐
。
这些文件在 Linux (Apache/php) 下得到了很好的处理:
$files = scandir($path);
echo json_encode($files);
file1⌐
file2⌐
file3⌐
file4⌐
在Windows下,它们似乎被文件系统读取为Windows-1252,所以我不得不有条件地转换它们,以便json_encode
可以工作
$files = scandir($path);
foreach ($files as $i => $file) {
$files[$i] = mb_convert_encoding($file, 'UTF-8', 'Windows-1252');
}
echo json_encode($files);
这是他们如何转换的
file1¬
file2¬
file3¬
file4¬
为什么 ⌐
被转换为 ¬
我怎样才能得到原始字符?
请尝试对文件名的关键字符 ⌐ 进行 unpack('C*', $char) 。然后您会注意到它已经是 0xAC(即 ¬)。
原因是,scandir() 使用 Windows 的 8 位 ANSI Api 进行替换,并为不存在的字符提供一些 "closest matching character" Windows-1252。如果您使用文本编辑器 notepad++,将其设置为 ANSI 并尝试将您的 ⌐ 复制并粘贴到其中,您可以观察到相同的行为。它会显示为 ¬(有趣的是,当我在我的系统上尝试它时,它在 c&p 缓冲区中也发生了变化)。
你能做什么?那么这里有一些选项:
- 在Windows上使用shell_exec('dir /b')(我测试了这个,你得到了原始字符)
- 假设 ¬ 对 Windows 上的文件名表示 ⌐ 并在 utf-8 转换后将其替换回去
- 更改您的软件系统,使字符 ⌐ 不再用于文件名
- 使用一些具有函数 stream_encoding 的实验性 php 构建并尝试下面的代码。 (注意:stream_encoding 未定义,即使在以下官方版本中加载了 mbstring:5.6.19 7.0.4)
$myContext = stream_context_create();
stream_encoding($myContext, 'UTF-8');
$files = scandir('./', SCANDIR_SORT_ASCENDING, $myContext);
虽然通常应避免使用 shell_exec,但我认为这是您目前的最佳选择。从长远来看,如果可以的话,你应该选择 3。我不会推荐 4.(我也没有测试过)而且我对你的场景了解不够,无法判断 2. 是否可行。
我有文件名中包含字符 ⌐
。
这些文件在 Linux (Apache/php) 下得到了很好的处理:
$files = scandir($path);
echo json_encode($files);
file1⌐
file2⌐
file3⌐
file4⌐
在Windows下,它们似乎被文件系统读取为Windows-1252,所以我不得不有条件地转换它们,以便json_encode
可以工作
$files = scandir($path);
foreach ($files as $i => $file) {
$files[$i] = mb_convert_encoding($file, 'UTF-8', 'Windows-1252');
}
echo json_encode($files);
这是他们如何转换的
file1¬
file2¬
file3¬
file4¬
为什么 ⌐
被转换为 ¬
我怎样才能得到原始字符?
请尝试对文件名的关键字符 ⌐ 进行 unpack('C*', $char) 。然后您会注意到它已经是 0xAC(即 ¬)。
原因是,scandir() 使用 Windows 的 8 位 ANSI Api 进行替换,并为不存在的字符提供一些 "closest matching character" Windows-1252。如果您使用文本编辑器 notepad++,将其设置为 ANSI 并尝试将您的 ⌐ 复制并粘贴到其中,您可以观察到相同的行为。它会显示为 ¬(有趣的是,当我在我的系统上尝试它时,它在 c&p 缓冲区中也发生了变化)。
你能做什么?那么这里有一些选项:
- 在Windows上使用shell_exec('dir /b')(我测试了这个,你得到了原始字符)
- 假设 ¬ 对 Windows 上的文件名表示 ⌐ 并在 utf-8 转换后将其替换回去
- 更改您的软件系统,使字符 ⌐ 不再用于文件名
- 使用一些具有函数 stream_encoding 的实验性 php 构建并尝试下面的代码。 (注意:stream_encoding 未定义,即使在以下官方版本中加载了 mbstring:5.6.19 7.0.4)
$myContext = stream_context_create();
stream_encoding($myContext, 'UTF-8');
$files = scandir('./', SCANDIR_SORT_ASCENDING, $myContext);
虽然通常应避免使用 shell_exec,但我认为这是您目前的最佳选择。从长远来看,如果可以的话,你应该选择 3。我不会推荐 4.(我也没有测试过)而且我对你的场景了解不够,无法判断 2. 是否可行。