Подтвердить что ты не робот

File_exists() возвращает false, но файл существует

У меня очень странная проблема с file_exists(). Я использую эту функцию, чтобы проверить, существуют ли 2 разных файла в одних и тех же папках. Я дважды проверял, они оба существуют.

echo $relative . $url['path'] . '/' . $path['filename'] . '.jpg';
Result: ../../images/example/001-001.jpg

echo $relative . $url['path'] . '/' . $path['filename'] . '.' . $path['extension'];
Result: ../../images/example/001-001.PNG

Теперь позвольте использовать file_exists() на них:

var_dump(file_exists($relative . $url['path'] . '/' . $path['filename'] . '.jpg'));
Result: bool(false)

var_dump(file_exists($relative . $url['path'] . '/' . $path['filename'] . '.' . $path['extension']));
Result: bool(true)

Я не понимаю - оба эти файла существуют. Я запускаю Windows, поэтому он не связан с проблемой, чувствительной к регистру. Безопасный режим выключен.

Однако стоит упомянуть, что .png загружается пользователем через FTP, а .jpg создается с помощью script. Но, насколько я знаю, это не должно меняться.

Любые советы?

Спасибо

4b9b3361

Ответ 1

Результаты file_exists() кэшируются, поэтому попробуйте использовать clearstatcache(). Если это не помогло, перепроверьте имена - они могут быть похожими, но не одинаковыми.

Ответ 2

file_exists() просто не работает с HTTP-адресами.

Он поддерживает только пути файловой системы (и FTP, если вы используете PHP5.)

Обратите внимание:

Работы:

if  (file_exists($_SERVER['DOCUMENT_ROOT']."/folder/test.txt") 
    echo "file exists";

Не работает:

if (file_exists("www.mysite.com/folder/test.txt") 
    echo "file exists";

Ответ 3

Это из-за безопасного режима. Вы можете отключить его или включить каталог в safe_mode_include_dir. Или измените владельца/права доступа к этим файлам.

php.net: file_exists()
php.net: безопасный режим

Ответ 4

Я обнаружил, что для проверки того, существует ли файл (относительно текущего php файла, из которого он выполняется), мне помогает следующий фрагмент кода:

$filename = 'myfile.jpg';
$file_path_and_name = dirname(__FILE__) . DIRECTORY_SEPARATOR . "{$filename}";
if ( file_exists($file_path_and_name) ){
  // file exists. Do some magic...              
} else {
  // file does not exists...
}

Ответ 5

Просто мой $.02: у меня была эта проблема, и это было из-за пробела в конце имени файла. Это не всегда проблема пути - хотя это первое, что я проверяю - всегда. Я мог бы вырезать и вставить имя файла в окно оболочки с помощью команды ls -l и, конечно же, найти файл, потому что в командной строке будет игнорироваться пространство, в котором нет файлов file_exists. Очень расстраивать действительно и почти невозможно найти, если бы не StackOverflow.

СОВЕТ. При выводе операторов отладки заключают значения с разделителями() или [], и это будет ясно отображать пробел. И всегда помните, чтобы обрезать ваш вход.

Ответ 6

Попробуйте использовать DIRECTORY_SEPARATOR вместо '/' в качестве разделителя. Windows использует другой разделитель для путей файловой системы (обратная косая черта), чем системы Linux и Unix.

Ответ 7

Это также может быть проблема разрешения в одной из родительских папок или самого файла.

Попробуйте открыть сеанс как пользователь, на котором запущен ваш веб-сервер и cd. Папка должна быть доступна этому пользователю, и файл должен быть доступен для чтения.

Если нет, php вернет, что файл не существует.

Ответ 8

Очень простой трюк здесь, который работал на меня.

Когда я пишу следующую строку, она возвращает false.

if(file_exists('/my-dreams-files/'.$_GET['article'].'.html'))

И когда я пишу с удалением URL-адреса, начинающегося слэш, он возвращает true.

if(file_exists('my-dreams-files/'.$_GET['article'].'.html'))

Ответ 9

У меня есть новая причина, по которой это происходит - я использую PHP внутри контейнера Docker со смонтированным томом для кодовой базы, которая находится на моем локальном хост-компьютере.

Я получал file_exists == FALSE (внутри Composer autoload), но если я скопировал filepath в терминал - он действительно существовал! Я попробовал clearstatche(), проверил, что безопасный режим отключен.

Затем я вспомнил сопоставление тома Docker: абсолютный путь на моем локальном хосте определенно не существует в контейнере Docker - это взгляд PHP на мир.

(Я постоянно забываю, что использую Docker, потому что я создал функции оболочки, которые так красиво оборачивают команды запуска Docker...)

Ответ 10

Вы пробовали ручную запись. также ваши два расширения, похоже, в другом случае

   var_dump(file_exists('../../images/example/001-001.jpg'));
   var_dump(file_exists('../../images/example/001-001.PNG'));

Ответ 11

Функция custom_file_exists(), вдохновленная ответами @Timur, @Brian, @Doug и @Shahar:

function custom_file_exists($file_path=''){
    $file_exists=false;

    //clear cached results
    //clearstatcache();

    //trim path
    $file_dir=trim(dirname($file_path));

    //normalize path separator
    $file_dir=str_replace('/',DIRECTORY_SEPARATOR,$file_dir).DIRECTORY_SEPARATOR;

    //trim file name
    $file_name=trim(basename($file_path));

    //rebuild path
    $file_path=$file_dir."{$file_name}";

    //If you simply want to check that some file (not directory) exists, 
    //and concerned about performance, try is_file() instead.
    //It seems like is_file() is almost 2x faster when a file exists 
    //and about the same when it doesn't.

    $file_exists=is_file($file_path);

    //$file_exists=file_exists($file_path);

    return $file_exists;
}

Ответ 12

Этот ответ может быть немного взломан, но он работает для меня -

$file = 'path/to/file.jpg';
$file = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].'/'.$file;
$file_headers = @get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
    $exists = false;
}else{
    $exists = true;
}

По-видимому, $_SERVER['REQUEST_SCHEME'] является немного рискованным для использования с IIS 7.0 + PHP 5.3, чтобы вы могли найти лучший способ добавить в протокол.

Я нашел этот ответ здесь http://php.net/manual/en/function.file-exists.php#75064

Ответ 13

Последние два часа я размышлял, что не так с моим утверждением if: file_exists($file) возвращал false, однако я мог без проблем позвонить include($file).

Оказывается, я не осознавал, что значение php include_path, которое я установил в файле .htaccess, не переносилось в file_exists, is_file и т.д.

Таким образом:

<?PHP
// .htaccess php_value include_path '/home/user/public_html/';

// includes lies in /home/user/public_html/includes/

//does not work, file_exists returns false
if ( file_exists('includes/config.php') )
{
     include('includes/config.php');
}

//does work, file_exists returns true
if ( file_exists('/home/user/public_html/includes/config.php') )
{
    include('includes/config.php');
}
?>

Это просто говорит о том, что "ярлыки для простоты", такие как установка include_path в .htaccess, могут в конечном итоге привести к еще большему горе.