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

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

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

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

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


person Lan    schedule 20.08.2013    source источник
comment
Какая версия PHP? Обертки URL-адресов могут быть только на версиях = ›PHP 5.0.0   -  person Amal Murali    schedule 20.08.2013
comment
Пробовали ли вы следующую рекомендацию из документации для file_exists(): Примечание: результаты этой функции кэшируются. См. Clearstatcache () для получения более подробной информации.   -  person Tomas Creemers    schedule 20.08.2013
comment
да, я пробовал clearstatcache () - но кеш будет хранить его как «существует», и моя проблема в том, что он не находит его - так что это определенно не виноват.   -  person Lan    schedule 20.08.2013
comment
Могут дать пример вашей структуры каталогов и местоположения запускаемых скриптов, которые включают некоторые другие скрипты и где заканчиваются записи.   -  person Manwe    schedule 26.08.2013


Ответы (6)


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

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

is_file(__DIR__ . DIRECTORY_SEPARATOR . $path);

Чтобы проверить наличие файла вне PHAR.

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

РЕДАКТИРОВАТЬ: На самом деле вы также можете использовать dirname(Phar::running(false)) для получения папки PHAR из любого места в PHAR. Эта функция возвращает пустую строку, если вы не в PHAR, поэтому независимо от того, выполняется ли ваше приложение как PHAR или напрямую, оно должно работать нормально, например

$pharFile = Phar::running(false);
is_file(('' === $pharFile ? '' : dirname($pharFile) . DIRECTORY_SEPARATOR) . $path)
person boen_robot    schedule 26.08.2013
comment
Использование __DIR__ определенно не работает, ни с помощью специальной заглушки, ни даже чуть-чуть. Он вернет текущий рабочий каталог phar, а __FILE__ вернет имя phar. - person Alex Barker; 10.01.2020

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

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

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

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

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

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

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

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

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

отметка

person Mark Wu    schedule 03.12.2013

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

Работа с путями к файлам и архивами Phar в 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. Наш файл начальной загрузки просто вызовет объявление функции «does_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"

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

person Vineet1982    schedule 22.08.2013
comment
знаю, знаю. вопрос не в этом. мой пакет phar создает новый файл ВНЕ сценария phar, используя fwrite. работает отлично, создается новый файл. и это новое можно позже прочитать с помощью include или require, но его нельзя увидеть с помощью file_exists - это моя проблема - я думаю, что это может быть ошибка в phar - person Lan; 22.08.2013
comment
@Lan ответил на ваш вопрос - person Vineet1982; 22.08.2013
comment
спасибо, но если include ('login.php') или require ('login.php') найдет и прочитает файл, то, конечно, if (file_exists ('login.php')) вернет true - конечно, благодаря тому факту, что его чтение с помощью include / require показывает, что путь / местоположение файла верны, и это не проблема? - person Lan; 22.08.2013
comment
@Lan Изменил ответ, чтобы легче было понять, как работает - person Vineet1982; 24.08.2013
comment
эй, спасибо, чувак, я думаю, я начинаю понимать, что ты говоришь. Но моя проблема в том, что ВНУТРИ моего файла phar я хочу проверить файл ВНЕШНИЙ. когда я запускаю свой файл phar, он создает 'login.php' в том же каталоге, что и phar, но вне его. затем, когда вы снова запустите phar, мне нужно, чтобы он проверил, есть ли этот login.php снаружи. какой путь к файлу я использую для этого? - person Lan; 24.08.2013
comment
Я не знаю, что ты пытаешься сделать, так как это зависит от кода, но уловка есть - person Vineet1982; 24.08.2013
comment
Этот ответ был взят из mangstacular.blogspot .co.uk / 2011/06 / - person Quolonel Questions; 11.02.2015

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

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

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

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

if (file_exists(realpath($filename)) { /* file exists on filesystem */ }
person netcoder    schedule 26.08.2013

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

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

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

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

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

person Zaffy    schedule 25.08.2013

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

 function fileExists($path){
    //try to open the file, if it can be read the file exist
    return (@fopen($path,"r") == true); 
 }
person Konsole    schedule 25.08.2013
comment
ааа хорошая идея. благодаря. мне нужно закрыть его потом, чтобы он оставался более законным? - person Lan; 25.08.2013
comment
Да, конечно! Вы можете закрыть его позже, если функция fopen завершится успешно. Откройте файл, в случае успеха закройте файл и верните true, иначе верните false. - person Konsole; 25.08.2013