file_exists() returns false, but the file DOES exist

72,576

Solution 1

Results of the file_exists() are cached, so try using clearstatcache(). If that not helped, recheck names - they might be similar, but not same.

Solution 2

file_exists() just doesn't work with HTTP addresses.

It only supports filesystem paths (and FTP, if you're using PHP5.)

Please note:

Works :

if  (file_exists($_SERVER['DOCUMENT_ROOT']."/folder/test.txt") 
    echo "file exists";

Does not work:

if (file_exists("www.mysite.com/folder/test.txt") 
    echo "file exists";

Solution 3

I found that what works for me to check if a file exists (relative to the current php file it is being executed from) is this piece of code:

$filename = 'myfile.jpg';
$file_path_and_name = dirname(__FILE__) . DIRECTORY_SEPARATOR . "{$filename}";
if ( file_exists($file_path_and_name) ){
  // file exists. Do some magic...              
} else {
  // file does not exists...
}

Solution 4

It's because of safe mode. You can turn it off or include the directory in safe_mode_include_dir. Or change file ownership / permissions for those files.

php.net: file_exists()
php.net: safe mode

Solution 5

Just my $.02: I just had this problem and it was due to a space at the end of the file name. It's not always a path problem - although that is the first thing I check - always. I could cut and paste the file name into a shell window using the ls -l command and of course that locates the file because the command line will ignore the space where as file_exists does not. Very frustrating indeed and nearly impossible to locate were it not for StackOverflow.

HINT: When outputting debug statements enclose values with delimiters () or [] and that will show a space pretty clearly. And always remember to trim your input.

Share:
72,576
Bv202
Author by

Bv202

.NET Software Engineer SOreadytohelp

Updated on December 22, 2020

Comments

  • Bv202
    Bv202 over 3 years

    I'm having a very weird issue with file_exists(). I'm using this function to check if 2 different files in the same folders do exist. I've double-checked, they BOTH do exist.

    echo $relative . $url['path'] . '/' . $path['filename'] . '.jpg';
    Result: ../../images/example/001-001.jpg
    
    echo $relative . $url['path'] . '/' . $path['filename'] . '.' . $path['extension'];
    Result: ../../images/example/001-001.PNG
    

    Now let's use file_exists() on these:

    var_dump(file_exists($relative . $url['path'] . '/' . $path['filename'] . '.jpg'));
    Result: bool(false)
    
    var_dump(file_exists($relative . $url['path'] . '/' . $path['filename'] . '.' . $path['extension']));
    Result: bool(true)
    

    I don't get it - both of these files do exist. I'm running Windows, so it's not related to a case-sensitive issue. Safe Mode is off.

    What might be worth mentioning though is that the .png one is uploaded by a user via FTP, while the .jpg one is created using a script. But as far as I know, that shouldn't make a difference.

    Any tips?

    Thanks

  • Bv202
    Bv202 almost 13 years
    Safe mode is already turned off, so that's not the issue. Also, the permissions should be file-specific, as they're both in the same folder. I've never had these issues in Windows, but when looking at the permissions, I don't see any difference between the two...
  • ace
    ace almost 13 years
    Ah, sorry didn't see safe mode is off. If permissions are the same, you might need to check the owner id or the group id for those files, it could be that your webuser doesn't belong to the group or is not the owner of the file.
  • Bv202
    Bv202 almost 13 years
    This was indeed the problem. It seemed the script replaced _'s with -'s. Very hard to miss (and annoying) :|
  • Timur
    Timur almost 13 years
    Similar things happen with sometimes :)
  • Curtis Gibby
    Curtis Gibby over 11 years
    Of course I find this answer after I resolve this exact same issue on my own!
  • happy_marmoset
    happy_marmoset about 10 years
    it is DIRECTORY_SEPARATOR?
  • Doug
    Doug about 10 years
    Yes, it is, @happy_marmoset. I corrected the answer. Thanks!
  • Luca Rainone
    Luca Rainone over 9 years
    you're missing custom_basename function declaration
  • RafaSashi
    RafaSashi over 9 years
    Thanks chumkiu basename() will be enough in this case
  • instead
    instead almost 9 years
    For me clearstatcache() - didn't helped but... My class name was Multimedia. Then i used clearstatcache() - still didn't work. Then i renamed file to Multimedia2 didn't helped to. That was strange. Then I renamed file to Abc. It worked... Then renamed to Multimedia and it worked again :D It took me about half an hour...
  • Mo Beigi
    Mo Beigi over 8 years
    I ran into an issue, to fix it I ensured that the path did not start with a /
  • John Christian De Chavez
    John Christian De Chavez almost 8 years
    I also had problem with these. because i supplied file_exists() a full path. it shouldn't be a full path. for example www.abc.com/photo.jpg, you should supply only photo.jpg not with domain.
  • conrad10781
    conrad10781 over 7 years
    This seems to be expected, provided that my-dreams-files is not in the root of the drive. / with nothing in front of it is the root. Your second example is relative.
  • Ligemer
    Ligemer almost 7 years
    Best to use trim(). Gets me every time.
  • Genjo
    Genjo over 6 years
    Note that safe_mode has been removed in PHP 5.4.0.
  • EgoistDeveloper
    EgoistDeveloper about 6 years
    In my case PHP version is 7.1.2 bu same issue. You're answer correct and working.
  • arroni
    arroni over 5 years
    Thanks, this was the case for me.
  • pipwerks
    pipwerks over 5 years
    I would like to upvote this 1000 times! I spent hours thinking it was a permissions issue but all I needed to do was remap my PHP script from /Volumes/MyDrive to /var/www/html. Thanks for the reminder
  • Richard Bernstein
    Richard Bernstein about 4 years
    I have the same problem. Not being a Docker expert, I am not sure how to remap. When I try $iRc=file_exists("/opt/docker-substantiator/app/assets/image‌​_crud/views/list.php‌​");, which is the full path on the host, it fails. Of course on the cmd line ls /opt/docker-substantiator/app/assets/image_crud/views/list.p‌​hp works fine. What should the path be to list.php in my container?
  • scipilot
    scipilot about 4 years
    @RichardBernstein it depends how you mounted the volume. You just have to make sure your app is using a path which is according to the container's filesystem, not the host's. I would jump inside it to check it's right using docker exec -it container-name bash then poke around until you understand the inner filesystem. You can figure it out from the volume mapping (e.g. -v /Volumes/MyDrive:/var/www/html) but seeing it place makes it clearer.
  • scipilot
    scipilot about 4 years
    @RichardBernstein but if your path /opt/docker-substantiator/app/assets/image_crud/views/list.p‌​hp is correct within the container (i.e. it's not a path on your host / your dev machine), then you have may a different problem.
  • Richard Bernstein
    Richard Bernstein about 4 years
    Thanks scipilot. I think that the issue is the mapping as you state. I loaded up bash and I see :/app#. I guess I need to learn the commands to see the inner filesystem. I didnt create the original containers so I don't know where the docker run got its mount instructs from. Thx again.
  • Richard Bernstein
    Richard Bernstein about 4 years
    I did manage to cd to root@6adf4b4936f7:/app/assets/image_crud/views#. But when I $iRc=file_exists("/assets/image_crud/views/list.php");, it still fails.
  • scipilot
    scipilot about 4 years
    Why don't you open a new question so we can help you properly? I think you're missing the leading /app/
  • Emmanuel BRUNO
    Emmanuel BRUNO over 3 years
    clearstatcache() is not usefull here : according to the doc, PHP doesn't cache information about non existent files. So if file_exists returns false instead of true, file status cache has nothing to do with it. If, on the other hand, file_exists returns true intsead of false, clearstatecache might be a solution. @see php.net/manual/en/function.clearstatcache.php