В настоящее время я пытаюсь проверить с помощью PHP, существует ли файл. Текущий файл, который я пытаюсь проверить, если он существует, содержит апостроф, файл называется: 13067-AP-03 A — Ситуация 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);
Ни один из которых не работал. Я также попробовал:
setlocale(LC_ALL, "en_US.utf8");
Возможно, стоит заметить, что когда я получаю имя файла прямо из PHP, я получаю следующее:
13067-AP-03 A — Ситуация projet 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 под Windows. Я загрузил двоичную копию Windows в свою Windows, которая на японском языке, и успешно воспроизвела вашу проблему.
В соответствии с https://bugs.php.net/bug.php?id=47096
Итак, если у вас есть общее имя файла (вместе с его путем) в виде строки Unicode $ u (например, в кодировке UTF-8), и вы хотите попытаться сохранить его под этим именем в Windows, вы должны сначала проверить текущая локаль вызывает setlocale (LC_CTYPE, 0) для получения текущей кодовой страницы, затем вы должны преобразовать $ u в массив байтов в соответствии с кодовой страницей; если одна или несколько кодовых точек не имеют аналога в текущей кодовой странице, файл не может быть сохранен с этим именем из PHP. Dot.
Моя кодовая страница — CP932, которую вы можете увидеть, запустив chcp
в cmd.
Поэтому ожидается, что код будет:
$filename='C:\Users\Frederick\Desktop\13067-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 хранит имена файлов в Unicode. Напротив, старые файловые системы FAT12, FAT16 и FAT32 используют набор символов OEM.
Сама Windows использует UTF-16LE, который Microsoft называет Unicode, чтобы сохранить имена файлов. Но PHP не поддерживает имя файла в кодировке UTF-16LE.
В заключение очень жаль, что я не могу найти способ решить проблему, вместо того, чтобы избегать всех этих символов при именовании файлов, если вы работаете в Windows. И я тоже не думаю, что команда PHP решит проблему в будущем.
Убедитесь, что ваш текстовый редактор сохраняет файл как «UTF-8 без спецификации»
BOM — это Byte Order Mark, два байта, помещенные в начале файла, которые позволяют программному обеспечению считывать файл, чтобы определить, был ли он сохранен как с прямым порядком байтов или с прямым порядком байтов, однако интерпретатор PHP не может интерпретировать эти символы, и поэтому вы должны сохраните файл без метки порядка байтов.
Попробуйте это в начале вашего php файла:
<?php
header('Content-Type: text/html; charset=utf-8');
?>