Проблема PHP Phar – file_exists ()

Сценарий Phar создает новый файл с fwrite, который отлично работает, он создает новый файл за пределами phar в том же каталоге, что и файл phar.

Но тогда, когда я использую if (file_exists ('file.php')), он не подбирает его.

Но тогда включите и потребуйте забрать его.

Кто-нибудь знает об этой проблеме? Испытания и исследования на какое-то время, похоже, не могут найти решение.

    На заглушке PHAR вы можете использовать магическую константу __DIR__, чтобы получить папку файла PHAR.

    Имея это в виду, вы можете просто использовать

     is_file(__DIR__ . DIRECTORY_SEPARATOR . $path); 

    Проверить наличие файла вне PHAR.

    Вы можете ТОЛЬКО делать это из заглушки, и ТОЛЬКО, если это настраиваемый заглушка, а не один, созданный Phar :: setDefaultStub (). Если вам нужно проверить файлы дальше по строке, вам нужно будет как можно скорее получить значение этой константы, например, глобальную переменную, пользовательскую немагическую константу или статическое свойство или что-то еще, с чем советуют другие файлы.

    EDIT: На самом деле вы также можете использовать dirname(Phar::running(false)) чтобы получить папку PHAR из любой точки PHAR. Эта функция возвращает пустую строку, если вы не находитесь в PHAR, поэтому независимо от того, выполняется ли ваше приложение как PHAR или напрямую, оно должно работать нормально, например

     $pharFile = Phar::running(false); is_file(('' === $pharFile ? '' : dirname($pharFile) . DIRECTORY_SEPARATOR) . $path) 

    Работа с файловыми путями и файловыми архивами

    Работа с файловыми путями и файловыми архивами на PHP может быть сложной задачей. PHP-код внутри файла Phar будет относить относительные пути как относящиеся к архиву Phar, а не к текущему рабочему каталогу. Вот краткий пример:

    Скажем, у вас есть следующие файлы:

     phar/index.php test.php my.phar 

    Файл index.php находится внутри каталога phar. Это файл начальной загрузки для phar-архива:

     function does_it_exist($file){ return file_exists($file) ? "true" : "false"; } 

    Файл начальной загрузки выполняется, когда файл phar включен из скрипта PHP. Наш файл bootstrap просто приведет к объявлению функции «do_it_exist».

    Попробуем запустить другой код внутри test.php и посмотреть, какие результаты для каждого запуска:

     //Run 1: require_once 'phar/index.php'; //PHP file $file = __DIR__ . "/index.php"; //absolute path echo does_it_exist($file); //prints "false" //Run 2: require_once 'phar/index.php'; //PHP file $file = "index.php"; //relative path echo does_it_exist($file); //prints "false" //Run 3: require_once 'my.phar'; //phar file $file = __DIR__ . "/index.php"; //absolute path echo does_it_exist($file); //prints "false" //Run 4: require_once 'my.phar'; //phar file $file = "index.php"; //relative path echo does_it_exist($file); //prints "true" 

    Посмотрите на Run 4. Этот код включает в себя файл phar и передает функции относительный путь. Относительно текущего рабочего каталога index.php не существует. Но по отношению к содержимому phar-архива он существует, поэтому он печатает «true»!

    Сегодня я встречаю тот же вопрос. Через несколько часов выкапываю … Я нашел ответ.

    Вы можете попробовать следующий сценарий?

     if(file_exists(realpath('file.php'))); 

    Если файл существует, тогда проблема

    если вы используете только имя файла без информации о пути, файл php treat связан с phar-заглушкой. например:

    phar:///a/b/c/file.php

    Таким образом, вы должны использовать абсолютный путь для управления файлом, например:

    /home/www/d/e/f/file.php

    Надеюсь, эта помощь.

    отметка

    Я могу воспроизвести это поведение, вызвав Phar::interceptFileFuncs() . Кажется, что вызовы fopen в режиме записи не перехватываются, а функции, связанные с статусом.

    Поскольку абсолютные имена файлов рассматриваются как связанные с файловой системой даже в архивах Phar, которые перехватывают функции файла:

    […] Предполагается, что абсолютными путями являются попытки загрузить внешние файлы из файловой системы.

    … одним из способов решения проблемы является использование realpath() :

     if (file_exists(realpath($filename)) { /* file exists on filesystem */ } 

    file_exists в php имеет несколько проблем, в частности случаев.

    Я рекомендую вам вместо этого использовать stat() , который обычно используется для получения этой информации,
    не только в php. Также не забудьте очистить кеш, вызвав clearstatcache() .

     function FileExists($filename) { clearstatcache(false, $filename); return false !== @stat($filename); } 

    Примечание. Я стараюсь избегать оператора подавления @ насколько могу, но я вижу, что этот конкретный случай необходим для его использования 🙂

    Не уверен, что вызывает file_exists() но вы можете попробовать что-то вроде этого

      function fileExists($path){ //try to open the file, if it can be read the file exist return (@fopen($path,"r") == true); }