file_exists() returns false, but the file DOES exist

后端 未结 14 1207
一向
一向 2020-12-05 09:40

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 ex

相关标签:
14条回答
  • 2020-12-05 10:16

    Try using DIRECTORY_SEPARATOR instead of '/' as separator. Windows uses a different separator for file system paths (backslash) than Linux and Unix systems.

    0 讨论(0)
  • 2020-12-05 10:18

    In my case, the problem was a misconception of how file_exists() behaves with symbolic links and .. ("dotdot" or double period) parent dir references. In that regard, it differs from functions like require, include or even mkdir().

    Given this directory structure:

    /home/me/work/example/
      www/
    /var/www/example.local/
      tmp/
      public_html -> /home/me/work/example/www/
    

    file_exists('/var/www/example.local/public_html/../tmp/'); would return FALSE even though the subdir exists as we see, because the function traversed up into /home/me/work/example/ which does not have that subdir.


    For this reason, I have created this function:

    /**
     * Resolve any ".." ("dotdots" or double periods) in a given path.
     *
     * This is especially useful for avoiding the confusing behavior `file_exists()`
     * shows with symbolic links.
     *
     * @param string $path
     *
     * @return string
     */
    function resolve_dotdots( string $path ) {
    
        if (empty($path)) {
            return $path;
        }
    
        $source = array_reverse(explode(DIRECTORY_SEPARATOR, $path));
        $balance = 0;
        $parts = array();
    
        // going backwards through the path, keep track of the dotdots and "work
        // them off" by skipping a part. Only take over the respective part if the
        // balance is at zero.
        foreach ($source as $part) {
            if ($part === '..') {
                $balance++;
    
            } else if ($balance > 0) {
                $balance--;
    
            } else {
                array_push($parts, $part);
            }
        }
    
        // special case: path begins with too many dotdots, references "outside
        // knowledge".
        if ($balance > 0) {
            for ($i = 0; $i < $balance; $i++) {
                array_push($parts, '..');
            }
        }
    
        $parts = array_reverse($parts);
        return implode(DIRECTORY_SEPARATOR, $parts);
    }
    
    0 讨论(0)
  • 2020-12-05 10:20

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

    0 讨论(0)
  • 2020-12-05 10:23

    have you tried manual entry. also your two extensions seem to be in different case

       var_dump(file_exists('../../images/example/001-001.jpg'));
       var_dump(file_exists('../../images/example/001-001.PNG'));
    
    0 讨论(0)
  • 2020-12-05 10:24

    A custom_file_exists() function inspired by @Timur, @Brian, @Doug and @Shahar previous answers:

    function custom_file_exists($file_path=''){
        $file_exists=false;
    
        //clear cached results
        //clearstatcache();
    
        //trim path
        $file_dir=trim(dirname($file_path));
    
        //normalize path separator
        $file_dir=str_replace('/',DIRECTORY_SEPARATOR,$file_dir).DIRECTORY_SEPARATOR;
    
        //trim file name
        $file_name=trim(basename($file_path));
    
        //rebuild path
        $file_path=$file_dir."{$file_name}";
    
        //If you simply want to check that some file (not directory) exists, 
        //and concerned about performance, try is_file() instead.
        //It seems like is_file() is almost 2x faster when a file exists 
        //and about the same when it doesn't.
    
        $file_exists=is_file($file_path);
    
        //$file_exists=file_exists($file_path);
    
        return $file_exists;
    }
    
    0 讨论(0)
  • 2020-12-05 10:25

    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

    0 讨论(0)
提交回复
热议问题