2

我使用 mkdir() 通过 PHP 以波斯语和阿拉伯语创建了一些目录。

我想将文件夹移动到 Windows 中,但文件夹名称有问题。

示例:我写了:“سلام”

但在 Windows 中显示未知字符:“ط³غŒط³طھظ... ط¹ط§ظ...ظ„ ط¬ظ„ط¯ ط¯ظˆظ...”

似乎它应该转换为除 UTF-8 之外的其他编码

对不起,如果我的英语不是很好。

谢谢你。

编辑:我使用了这个 Powershell 代码并为我工作:

Get-ChildItem | ForEach-Object {
  $filename = Split-Path -Leaf $_
  $new = [Text.Encoding]::Utf8.GetString([Text.Encoding]::Default.GetBytes($filename))
  if ($_.Name -ne $new) {
    Rename-Item $_ $new
  }
}
enter code here

但我也希望上面的代码更正所有子文件夹名称......

4

1 回答 1

3

似乎它应该转换为除 UTF-8 之外的其他编码

是的:当您在 C 标准库基于字节的文件接口(这是 PHP 和大多数其他跨平台语言所做的)中使用文件名字符串时,您将获得 Windows 默认 ('ANSI') 代码页。这种编码是依赖于语言环境的,而且从来不是 UTF-8。

从上述文件名来看,您的默认代码页是 1256 阿拉伯语。如果您将文件名编码为 cp1256 那么应该可以:

$localfilename= iconv('utf-8', 'windows-1256', $filename);

然而:

  • 这意味着您只能在文件名中使用阿拉伯(和 ASCII)字符 - 任何其他 Unicode 字符都会中断;

  • 如果部署在默认代码页不是 1256 的其他服务器上,这自然会失败。服务器通常在美国语言环境中运行并选择代码页为 1252 西欧的服务器。

虽然您通常可以更改代码页,并且 UTF-8 原则上在 Windows 中作为代码页 65001 可用,但它存在许多错误,可能使其无法用于此目的 - UTF-8 是二等公民在 Windows 下。(在任何情况下,在 Web 服务器线程中更改区域设置都是不可靠的。)

让完整的 Unicode 文件名在 Windows 中工作的唯一方法是调用本机 Win32 API 函数来访问文件(使用 UTF-16LE 字符串)而不是 C 标准库函数。这就是 PowerShell/.NET 所做的——因为它是特定于 Windows 的软件,它可以负担得起直接使用 Win32 功能。Python 还支持转到 Win32 而不是 C 的 Unicode 文件名。

但是 PHP 目前没有这个能力。您可以通过使用w32api_invoke_function直接调用 Win32 API CreateDirectoryW手动执行此操作,但这确实很不方便。

这就是为什么最好尽可能避免使用任意输入作为文件名的原因之一!

于 2013-04-09T10:40:13.490 回答