![将 PHP 应用程序从 Windows Server 2003 迁移到 Linux 时出现文件名编码问题](https://linux22.com/image/559296/%E5%B0%86%20PHP%20%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E4%BB%8E%20Windows%20Server%202003%20%E8%BF%81%E7%A7%BB%E5%88%B0%20Linux%20%E6%97%B6%E5%87%BA%E7%8E%B0%E6%96%87%E4%BB%B6%E5%90%8D%E7%BC%96%E7%A0%81%E9%97%AE%E9%A2%98.png)
我有几个 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:抱歉,原问题没有正确暴露问题,而且这么晚才给出解决方案