PHP 无法识别其中包含撇号的文件名

PHP doesn't recognize filename with apostrophe in it

目前我正在尝试检查 PHP 文件是否存在。我正在尝试检查的当前文件中是否存在撇号,文件是 called:13067-AP-03 A - Situation projetée.pdf.

我用来检查文件是否存在的代码是:

$filename = 'C:/13067-AP-03 A - Situation projetée.pdf';

if (file_exists($filename)) 
{
    echo "The file exists";
} else 
{
    echo "The file does not exist";
}

我现在面临的问题是,每当我尝试检查文件是否存在时,我都会收到它不存在的消息。如果我继续删除 é,我会收到该文件确实存在的消息。

看起来 PHP 以某种方式无法识别包含撇号的文件。我尝试了以下方法:

urlencode($filename);
addslashes($filename);
utf8_encode($filename);

None 其中有效。我也试过:

setlocale(LC_ALL, "en_US.utf8");

也许值得注意的是,当我直接从 PHP 获取文件名时,我得到以下信息: 13067-AP-03 A - 情境项目�e.pdf

我必须执行以下操作才能正确显示文件名:

$filename = iconv( "CP437", 'UTF-8', $filename);

我想知道以前是否有人遇到过同样的问题,可以帮助我解决这个问题。非常感谢所有帮助。

对于那些感兴趣的人,脚本在 windows 机器上运行。

奇怪的是,这有效:我将所有源代码从 Sublime Text 3 复制到记事本。我继续通过覆盖 PHP 文件将源代码保存在记事本中。

现在,当我检查文件是否存在时,它显示存在以下文件名:

13067-AP-03 A - Situation projet�e.pdf

我现在面临的唯一问题是我想使用 file_get_contents 下载文件。但是 file_get_contents 没有将 � 插入为撇号。

在您的 php 文件开始时试试这个:

<?php
header('Content-Type: text/html; charset=utf-8');
?>

确保您的文本编辑器将文件另存为 "UTF-8 without BOM"

BOM 是字节顺序标记,位于文件开头的两个字节允许软件读取文件以确定它是保存为小端还是大端,但是 PHP解释器无法解释这些字符,因此您必须在不带字节顺序标记的情况下保存文件。

我认为是Windows下的PHP的问题。我下载了一个 Windows 二进制副本给我的 Windows 他是日语的,并成功地重现了你的问题。

根据https://bugs.php.net/bug.php?id=47096

So, if you have a generic name of a file (along with its path) as a Unicode string $u (for example UTF-8 encoded) and you want to try to save it with that name under Windows, you must first check the current locale calling setlocale(LC_CTYPE, 0) to retrieve the current code page, then you must convert $u to an array of bytes according to the code page; if one or more code points have no counterpart in the current code page, the file cannot be saved with that name from PHP. Dot.

我的代码页是CP932,你可以在cmd中运行 chcp看到你的

所以代码应该是:

$filename='C:\Users\Frederick\Desktop067-AP-03 A - Situation projetée.pdf';
$filename=mb_convert_encoding($filename, 'CP932', 'UTF-8');
var_dump($filename);
var_dump(file_exists($filename));

但这行不通!为什么?因为CP932不包含é!

这个字符

根据https://msdn.microsoft.com/en-us/library/windows/desktop/dd317748%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

NTFS stores file names in Unicode. In contrast, the older FAT12, FAT16, and FAT32 file systems use the OEM character set.

Windows本身使用UTF-16LE,微软称之为Unicode,来保存它的文件名。但是 PHP 不支持 UTF-16LE 编码的文件名。

总之,很遗憾,如果您在 Windows 上工作,我找不到解决问题的方法,而不是在命名文件时转义所有这些字符。而且我也不认为PHP的团队以后会解决这个问题