PHP:如何创建unicode文件名

时间:2011-06-24 12:02:22

标签: php unicode filenames

我正在尝试在文件名中创建带有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 个答案:

答案 0 :(得分:10)

目前无法在Windows上完成(可能PHP 5.4将支持此方案)。在PHP中,您只能使用Windows set代码页编写文件名。如果代码页不包含字符,则无法使用它。更糟糕的是,如果Windows上的文件在其文件名中包含此类字符,则您将无法访问它。

在Linux中,至少使用ext *,这是一个不同的故事。您可以使用您想要的任何文件名,操作系统不关心编码。因此,如果您始终使用UTF-8中的文件名,那么您应该没问题。但是,排除了UTF-16,因为文件名不能包含值为0的字节。

答案 1 :(得分:5)

对我来说,下面的代码适用于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;

答案 2 :(得分:1)

使用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 );
?>

答案 3 :(得分:0)

文件名没有编码概念。你必须通过其他方式找出文件名。对于您的情况唯一重要的一点是,在大多数文件系统中,文件名是以空字符结尾的* byte *字符串,但在NTFS中,它是以空字符结尾的16位字符串。因此,您无法使用标准fopen - 类型函数来访问所有可能的NTFS文件名。

但是,如果您通过其他方式获取了现有文件的NTFS文件名,则可以使用Windows API函数GetShortPathName获取该文件的简称,可以fopen中使用。我不知道PHP是否允许您访问Windows API函数,但也许有人为此编写了一个模块或插件。