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

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

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

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

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

Ответ 1

В заглушке 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)

Ответ 2

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

Работа с файловыми путями и файловыми архивами на 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 script. Наш файл 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"!

Ответ 3

Сегодня я встречаю ту же проблему. После нескольких часов копания... Я нашел ответ.

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

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

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

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

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

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

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

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

Марк

Ответ 4

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

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

function FileExists($filename)
{
    clearstatcache(false, $filename);

    return false !== @stat($filename);
}

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

Ответ 5

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

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

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

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

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

Ответ 6

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

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