将 PHP 应用程序从 Windows Server 2003 迁移到 Linux 时出现文件名编码问题

将 PHP 应用程序从 Windows Server 2003 迁移到 Linux 时出现文件名编码问题

我有几个 PHP 应用程序实际上在 Windows 2003 Server 上运行。由于它们实际上在 Windows 上使用 PHP、Mysql 甚至 Apache,因此项目是将它们迁移到新的 Linux 服务器(基于 Debian)。

但是当用户上传的文件名称中使用“特殊字符”(非 ASCII 文件,如 éèàç)(这在法语中很常见)时,我遇到了问题。

例如文件“accusé réception.pdf”的存储方式如下:

$ ls
accus? r?ception.pdf

当我在 Linux 服务器上上传新文件时,似乎没有问题:文件将在 fs 上以该名称命名,但应用程序可以找到它。问题在于迁移的内容,文件可用,但应用程序找不到它!

我想知道问题出在哪里:

  • 文件系统字符/编码表,我认为它来自这里
  • 应用程序本身的 php 代码,这将是一个问题,因为我无法更改它。我可以提交错误请求,但我不确定它们何时会被修复。
  • 另一个问题

最重要的是,我需要找到一种方法来解决这个问题。由于这种情况只发生在迁移数据时,因此在将这些应用程序投入 Linux 服务器生产时,我可以编写脚本或调整 fs/php/whatever 来解决这个问题。

在此先感谢您的帮助。

注意:当应用程序找不到文件时,我的 Apache 日志中充满了“readdir() 期望参数 1 为资源,布尔值给出...”错误

答案1

Windows 通常使用 unicode 来编码非 ASCII 字符,因此如果您在 debian 服务器上使用 unicode 语言环境,则一切就绪。它不必是法语,因为您要使用的字符是法语特有的(刚刚测试过,我将 LANG 设置为 en_US.UTF-8,我可以创建一个具有您提到的名称的文件(“accusé réception.pdf”),它也会以这种方式显示。

有可能重音符号是存在的,只是无法显示。要测试这个理论,请将“ls”命令替换为“LANG=en_US.UTF8 ls”。如果它显示正确,则只是您的终端。只需在 shell 的启动文件(例如 .bashrc)中或在系统范围内的 /etc/default/locale 中设置您的 LANG 变量即可

答案2

我终于找到了一些有关我的问题的信息和解决方法。开发这些 php 应用程序的公司告诉我使用 iso-8859-1 来提供存储的文件,并以此方式配置 Apache。它没有解决我的问题,但给了我一个想法。

我使用了 convmvhttp://www.j3e.de/linux/convmv/man/(谢谢如何在 Linux 上辨别文件名的语言编码?)将文件名从 utf-8 (我认为复制到 debian 会使它们变成 utf-8)转换为 iso-8859-1

$ convmv -f utf-8 -t iso-8859-1 --no-test -r *

它解决了我的问题,因为我的应用程序现在可以找到存储的文件(迁移的文件和新的文件)。

唯一的问题是,在我的 shell 上我仍然无法正确看到文件名:

$ ls 
test ��.xls

$ LANG=fr_FR.UTF-8 ls
test ??.xls

但这只是‘小’问题。

ps:抱歉,原问题没有正确暴露问题,而且这么晚才给出解决方案

相关内容