Я использую fopen () для создания файлов с именами файлов на основе ввода пользователя. В большинстве случаев вход будет кириллицей. Я хочу видеть имена файлов на своем компьютере, но, похоже, они не имеют правильную кодировку, а моя ОС (Windows 10) отображает что-то вроде этого – «Р ™ РѕСЃРёС.txt».
Windows использует UTF-16, поэтому я попытался преобразовать кодировку переменной, где имя хранится в UTF-16, но я получил ошибки при использовании fopen, fwrite и fclose.
Это код:
<?php if(isset($_POST["submit"])) { $name = $_POST["name"]; $file = fopen("$name.txt", "a"); fwrite($file, $string); fclose($file); }?>
Это правда, что Windows и NTFS используют UTF-16 для имен файлов, поэтому вы можете читать и записывать файлы с символами Unicode в их имени.
Однако вам нужно вызвать соответствующую функцию, чтобы использовать Unicode: _wfopen()
(C runtime) или CreateFileW()
(Windows API). См. Какие кодировки являются именами файлов в NTFS, хранящимися как? ,
PHP fopen()
не вызывает ни одну из этих функций, он использует простой старый ANSI fopen()
, поскольку, по-видимому, PHP не скомпилирован с константой _UNICODE
которая приведет к преобразованию fopen()
в _wfopen()
и т. Д. (См. также Как открыть файл на PHP, который имеет символы Unicode в своем имени? и glob () не может найти имена файлов с многобайтными символами в Windows? ).
Ниже приведены несколько возможных решений.
Решение для базы данных: введите имя Unicode в таблице и используйте первичный ключ таблицы в качестве имени файла.
Вы также можете использовать транслитерацию (как объяснено в PHP: как создать имена файлов Unicode ), что заменит символы Unicode, которые недоступны в целевом наборе символов с похожими символами. См. Php.net/iconv :
$filename = iconv('UTF-8', 'ASCII//TRANSLIT', "Žluťoučký kůň\n"); // "Zlutoucky kun"
Обратите внимание, что это может вызвать конфликты, поскольку несколько разных символов Юникода могут быть транслитерированы в одни и те же последовательности символов ANSI.
Другое предложение, как показано в разделе Как использовать функции файловой системы в PHP, используя строки UTF-8? , является urlencode
имя файла (обратите внимание, что вы не должны напрямую передавать пользовательский ввод в файловую систему, как это, вы разрешаете пользователям перезаписывать системные файлы):
$name = urlencode($_POST["name"]) . ".txt"; $file = fopen($name, "a");
Если ваша конечная цель состоит в том, чтобы записывать файлы с именами Unicode без изменения какого-либо кода, вам придется скомпилировать PHP самостоятельно в Windows с использованием константы _UNICODE
и компилятора Microsoft, и надеемся, что это сработает. Наверное, нет.
В качестве альтернативы вы можете использовать предложение о том, как открыть файл на PHP, который имеет юникодные символы в своем имени? и использовать расширение WFIO , и обращаться к файлам через протокол wfio://
.
file_get_contents("wfio://你好.xml");