PHP Phar - file_exists() issue

耗尽温柔 提交于 2019-12-04 05:13:55

At the PHAR's stub, you can use the __DIR__ magic constant to get the PHAR file's folder.

With that in mind, you can simply use

is_file(__DIR__ . DIRECTORY_SEPARATOR . $path);

To check for a file's existence outside the PHAR.

You can ONLY do this from the stub, and ONLY if it's a custom stub, as opposed to one generated by Phar::setDefaultStub(). If you need to check for files further down the line, you'll have to make that constant's value available somehow, like a global variable, a custom non-magical constant or a static property or something, which other files then consult with.

EDIT: Actually, you can also use dirname(Phar::running(false)) to get the PHAR's folder from anywhere in the PHAR. That function returns an empty string if you're not within a PHAR, so whether your application is executed as a PHAR or directly, it should work fine, e.g.

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

I meet the same issue today. After several hours digging ... I found the answer.

Can you try the following script first?

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

If the file exist, then the issue is

if you use only the filename without path information, php treat file is related to phar stub. for example:

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

So, you have to use absolute path to manipulate the file, for example:

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

Hope this help.

Mark

Working with file paths and Phar archives

Working with file paths and Phar archives in PHP can be tricky. The PHP code inside of a Phar file will treat relative paths as being relative to the Phar archive, not relative to the current working directory. Here's a short example:

Say you have the following files:

phar/index.php
test.php
my.phar

The index.php file is located inside of the phar directory. It is the bootstrap file for the phar archive:

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

The bootstrap file is executed when the phar file is included from a PHP script. Our bootstrap file will simply cause the function "does_it_exist" to be declared.

Let's try running different code inside of test.php and see what the results are for each run:

//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"

Look at Run 4. This code includes the phar file and passes the function a relative path. Relative to the current working directory, index.php does not exist. But relative to the contents of the phar archive, it does exist, which is why it prints "true"!

I can reproduce this behavior by calling Phar::interceptFileFuncs(). It seems fopen calls in write mode are not intercepted, while stat-related functions are.

Since absolute filenames are treated as related to the filesystem even in Phar archives that intercept file functions:

[...] Absolute paths are assumed to be attempts to load external files from the filesystem.

...one way to deal with the problem is to use realpath():

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

file_exists in php has several issues, in particular cases.

I recommend you to use stat() instead, which is commonly preffered way to obtain that info,
not just in php. Also don't forget to clear the cache by calling clearstatcache().

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

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

Note : I try to avoid the suppress operator @ as much as I can but I see this particular case as neccessary to use it :)

Not sure what is causing file_exists() to fail but you can try something like this

 function fileExists($path){
    //try to open the file, if it can be read the file exist
    return (@fopen($path,"r") == true); 
 }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!