PHP: как создавать имена файлов в юникоде - PullRequest
7 голосов
/ 24 июня 2011

Я пытаюсь создать файлы с символами Unicode в именах файлов.Я не совсем знаю, какую кодировку мне следует использовать, или если это вообще возможно.

У меня есть этот файл, сохраненный в кодировке latin1:

$h = fopen("unicode_♫.txt", 'w');
fclose($h);

В UTF-8 это будетдекодировать как 'unicode_ ♫ .txt'.Он записывает это в версии latin1 на диск (что очевидно?).Мне нужно сохранить его так, как это выглядит при декодировании UTF-8.Я также пытался кодировать его с помощью UTF-16, но он тоже не работает.

Я использую PHP 5.2 и хотел бы, чтобы это работало с NTFS, ext3 и ext4.

Какэто можно сделать?

Ответы [ 4 ]

10 голосов
/ 24 июня 2011

В настоящее время это невозможно сделать в Windows (возможно, PHP 5.4 будет поддерживать этот сценарий). В PHP вы можете писать только имена файлов, используя заданную кодовую страницу Windows. Если кодовая страница не содержит символ , вы не сможете ее использовать. Хуже того, если у вас есть файл в Windows с таким символом в имени файла, у вас будут проблемы с доступом к нему.

В Linux, по крайней мере с ext *, это другая история. Вы можете использовать любые имена файлов, которые вам нужны, ОС не заботится о кодировке. Так что если вы постоянно используете имена файлов в UTF-8, у вас должно быть все в порядке. UTF-16, однако, исключен, поскольку имена файлов не могут содержать байтов со значением 0.

5 голосов
/ 01 ноября 2013

для меня приведенный ниже код хорошо работает на Win7 / ntfs, Apache 2.2.21.0 и PHP 5.3.8.0:

<?php
// this source file is utf-8 encoded

$fileContent = "Content of my file which contains Turkish characters such as şığŞİĞ";

$dirName = 'Dirname with utf-8 chars such as şığŞİĞ';
$fileName = 'Filename with utf-8 chars such as şığŞİĞ';

// converting encodings of names from utf-8 to iso-8859-9 (Turkish)
$encodedDirName = iconv("UTF-8", "ISO-8859-9//TRANSLIT", $dirName);
$encodedFileName = iconv("UTF-8", "ISO-8859-9//TRANSLIT", $fileName);

mkdir($encodedDirName);
file_put_contents("$encodedDirName/$encodedFileName.txt", $fileContent);

вы можете сделать то же самое для открытия файлов:

<?php
$fileName = "Filename with utf-8 chars such as şığ";
$fileContent = file_get_contents(iconv("UTF-8", "ISO-8859-9//TRANSLIT", "$fileName.txt"));
print $fileContent;
1 голос
/ 30 ноября 2013

Используя расширение com_dotnet PHP, вы можете получить доступ к Windows * Scripting.FileSystemObject, а затем делать все, что вам нужно, с именами файлов / папок UTF-8.

Я упаковал это как упаковщик потока PHP,поэтому его очень просто использовать:

https://github.com/nicolas-grekas/Patchwork-UTF8/blob/lab-windows-fs/class/Patchwork/Utf8/WinFsStreamWrapper.php

Сначала убедитесь, что расширение com_dotnet включено в вашем php.ini, затем включите обертку с помощью:

stream_wrapper_register('win', 'Patchwork\Utf8\WinFsStreamWrapper');

Наконец, используйте функции, к которым вы привыкли (mkdir, fopen, rename и т. Д.), Но перед вашим путем добавьте win://

Например:

<?php
$dir_name = "Depósito";
mkdir('win://' . $dir_name );
?>
0 голосов
/ 24 июня 2011

Имена файлов не имеют понятия кодировки. Вы должны выяснить имя файла другими способами. Единственный важный момент для вашей ситуации заключается в том, что в большинстве файловых систем имя файла представляет собой строку * byte * с нулевым символом в конце, но в NTFS это 16-битная строка с нулевым символом в конце. Следовательно, вы не можете использовать стандартные функции fopen -типа для доступа ко всем возможным именам файлов NTFS.

Однако, если вы получили NTFS-имя файла существующего файла другими способами, вы можете использовать функцию Windows API GetShortPathName, чтобы получить короткое имя файла, которое вы можете использовать в fopen. Я не знаю, позволяет ли PHP вам получить доступ к функциям Windows API, но, возможно, кто-то написал модуль или плагин для этого.

...