Rectangle 27 0

include PHP Phar file_exists() issue?


//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"
function does_it_exist($file){
  return file_exists($file) ? "true" : "false";
}
phar/index.php
test.php
my.phar

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

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

Say you have the following files:

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.

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

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:

hey thanks man, i think i'm starting to see what your saying. But my problem is that WITHIN my phar file, i want to check for a file OUTSIDE of it. when i run my phar file it creates 'login.php' in the same directory as the phar, but outside of it. then when you run the phar again, i need it to check if that login.php is there, outside. what file path do i use for that?

i know, i know. thats not the question. my phar package creates a new file OUTSIDE of the phar script using fwrite. that works perfectly, a new file is created. and this new can later be read by include or require but it cant be "seen" by file_exists - which is my problem - i think it might be a bug in phar

thanks, but if include('login.php') or require('login.php') both find and read the file, than surely if(file_exists('login.php')) would return true - surely by the fact that its read by include/require shows the file path/location is correct, and so that is not the issue?

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


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

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.

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


/home/www/d/e/f/file.php
if(file_exists(realpath('file.php')));
phar:///a/b/c/file.php

Can you try the following script first?

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

If the file exist, then the issue is

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

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

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


//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"
function does_it_exist($file){
  return file_exists($file) ? "true" : "false";
}
phar/index.php
test.php
my.phar

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

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

Say you have the following files:

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.

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

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:

hey thanks man, i think i'm starting to see what your saying. But my problem is that WITHIN my phar file, i want to check for a file OUTSIDE of it. when i run my phar file it creates 'login.php' in the same directory as the phar, but outside of it. then when you run the phar again, i need it to check if that login.php is there, outside. what file path do i use for that?

i know, i know. thats not the question. my phar package creates a new file OUTSIDE of the phar script using fwrite. that works perfectly, a new file is created. and this new can later be read by include or require but it cant be "seen" by file_exists - which is my problem - i think it might be a bug in phar

thanks, but if include('login.php') or require('login.php') both find and read the file, than surely if(file_exists('login.php')) would return true - surely by the fact that its read by include/require shows the file path/location is correct, and so that is not the issue?

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


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

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

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().

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

file_exists in php has several issues, in particular cases.

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


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

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

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.

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

With that in mind, you can simply use

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.

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


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

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

Yes ofcourse! You can close it afterwards if the fopen function succeed. Open the file, if it succeed close the file and return true, else return false.

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


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

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

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.

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

With that in mind, you can simply use

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.

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


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

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

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().

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

file_exists in php has several issues, in particular cases.

Note
Rectangle 27 0

include PHP Phar file_exists() issue?


/home/www/d/e/f/file.php
if(file_exists(realpath('file.php')));
phar:///a/b/c/file.php

Can you try the following script first?

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

If the file exist, then the issue is

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

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

Note