Неверно закодированный символ
У меня есть файлы, содержащие символ ⌐
в их названии.
Эти файлы хорошо обрабатываются в Linux (Apache/php):
$files = scandir($path);
echo json_encode($files);
Файл1⌐
файл2⌐
файл3⌐
файл4⌐
В 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);
Вот как они преобразуются
Файл1
файл2
файл3
файл4
Почему ⌐
преобразуется в ¬
и как я могу получить исходный символ?
1 answers
Пожалуйста, попробуйте распаковать ('C*', $char) на критическом символе ⌐ ваших имен файлов. Затем вы заметите, что это уже 0xAC (что и есть).
Причина этого в том, что scandir() использует 8-разрядный Api ANSI Windows, который выполняет подстановку и предоставляет некоторый "наиболее подходящий символ" для символов, которых нет в Windows-1252. Вы можете наблюдать такое же поведение, если получите текстовый редактор notepad++, установите для него значение ANSI и попробуйте скопировать и вставить в него свой ⌐. Он будет отображаться как (и забавно, что он также изменился в буфере c&p, когда я попробовал его в своей системе).
Что вы можете сделать? Ну вот несколько вариантов:
- Используйте shell_exec ('dir/b') в Windows (я проверил это, вы получите исходный символ)
- Предположим, что это означает ⌐ для имен файлов в Windows, и просто замените его обратно после преобразования utf-8
- Измените свою программную систему, чтобы символ ⌐ больше не использовался в именах файлов
- Используйте некоторую экспериментальную сборку 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.
.