我在使用file_exists()时遇到了一个非常奇怪的问题。我正在使用此功能来检查相同文件夹中是否存在2个不同的文件。我已经仔细检查了,他们确实存在。
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
现在让我们在这些上使用file_exists():
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)
我不明白 - 这两个文件都存在。我正在运行Windows,因此它与案例敏感问题无关。安全模式已关闭。
值得一提的是,.png文件是由用户通过FTP上传的,而.jpg文件是使用脚本创建的。但据我所知,这不应该有所作为。
任何提示?
由于
答案 0 :(得分:20)
file_exists()
的结果已缓存,因此请尝试使用clearstatcache()
。如果没有帮助,请重新检查名称 - 它们可能相似,但不相同。
答案 1 :(得分:12)
这是因为安全模式。您可以将其关闭或包含safe_mode_include_dir
中的目录。或者更改这些文件的文件所有权/权限。
答案 2 :(得分:12)
我发现检查文件是否存在(相对于正在执行的当前php文件)的作用是这段代码:
$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...
}
答案 3 :(得分:12)
file_exists()
仅适用于HTTP地址。
它只支持文件系统路径(如果您使用PHP5,则支持FTP。)
请注意:
工作:
if (file_exists($_SERVER['DOCUMENT_ROOT']."/folder/test.txt")
echo "file exists";
没有工作:
if (file_exists("www.mysite.com/folder/test.txt")
echo "file exists";
答案 4 :(得分:10)
只是我的$ .02:我刚遇到这个问题,这是由于文件名末尾有一个空格。它并不总是一个路径问题 - 虽然这是我检查的第一件事 - 总是如此。我可以使用ls -l命令将文件名剪切并粘贴到shell窗口中,当然,这会定位文件,因为命令行将忽略file_exists不存在的空间。确实非常令人沮丧,几乎不可能找到它,不适合StackOverflow。
提示:当输出调试语句时,使用分隔符()或[]包含值,这将非常清楚地显示空格。并且始终记得要减少你的输入。
答案 5 :(得分:2)
尝试使用DIRECTORY_SEPARATOR
代替'/'作为分隔符。 Windows使用与Linux和Unix系统不同的文件系统路径(反斜杠)分隔符。
答案 6 :(得分:1)
它也可能是其中一个父文件夹或文件本身的权限问题。
尝试以运行Web服务器的用户身份打开会话并进入其中。该用户必须可以访问该文件夹,并且该文件必须是可读的。
如果没有,php将返回该文件不存在。
答案 7 :(得分:1)
这里有一个非常简单的技巧。
当我写下面一行时,它会返回false。
if(file_exists('/my-dreams-files/'.$_GET['article'].'.html'))
当我写删除URL开始斜杠时,它返回true。
if(file_exists('my-dreams-files/'.$_GET['article'].'.html'))
答案 8 :(得分:1)
我有一个新的原因会发生这种情况-我在一个Docker容器内使用PHP,该容器的代码库已安装在本地主机上。
我正在file_exists == FALSE
(在Composer autoload
内部)获得,但是如果我将filepath
复制到终端中-它确实存在!我尝试了clearstatche()
,并检查了安全模式是否关闭。
然后,我想起了Docker卷映射:本地主机上的绝对路径当然在Docker容器中不存在-这是PHP对世界的看法。
(我忘了我在使用Docker,因为我已经制作了可以很好地包装docker run命令的shell函数...)
答案 9 :(得分:0)
你试过手动输入吗?你的两个扩展似乎也有不同的情况
var_dump(file_exists('../../images/example/001-001.jpg'));
var_dump(file_exists('../../images/example/001-001.PNG'));
答案 10 :(得分:0)
一个custom_file_exists()函数受@Timur,@ Brian,@ Doug和@Shahar的启发以前的答案:
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;
}
答案 11 :(得分:0)
这个答案可能有点hacky,但它一直在为我工作 -
$file = 'path/to/file.jpg';
$file = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].'/'.$file;
$file_headers = @get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
$exists = false;
}else{
$exists = true;
}
显然$_SERVER['REQUEST_SCHEME']
与 IIS 7.0 + PHP 5.3 一起使用有点冒险,所以你可以寻找一种更好的方法来添加协议。
答案 12 :(得分:0)
我花了最后两个小时想知道我的if语句出了什么问题:file_exists($file)
返回false,但我可以毫无问题地致电include($file)
。
事实证明我没有意识到我在include_path
文件中设置的php .htaccess
值没有转移到file_exists
,is_file
,等
因此:
<?PHP
// .htaccess php_value include_path '/home/user/public_html/';
// includes lies in /home/user/public_html/includes/
//doesn't work, file_exists returns false
if ( file_exists('includes/config.php') )
{
include('includes/config.php');
}
//does work, file_exists returns true
if ( file_exists('/home/user/public_html/includes/config.php') )
{
include('includes/config.php');
}
?>
只是为了表明“简单的快捷方式”,比如在.htaccess中设置include_path,从长远来看可能会造成更多的悲痛。
答案 13 :(得分:0)
在我的情况下,问题是对file_exists()
与符号链接和..
(“ dotdot”或双倍句号)父目录引用的行为有误解。在这方面,它不同于require
,include
甚至是mkdir()
之类的功能。
给出以下目录结构:
/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/');
将返回FALSE
,即使该子目录存在,因为该函数遍历到没有该子目录的/home/me/work/example/
。
由于这个原因,我创建了这个函数:
/**
* 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);
}
答案 14 :(得分:0)
我刚刚遇到了同样的问题,并以一种神秘的方式解决了它。插入文件路径后,我从 Windows 文件资源管理器复制。 file_exists() 不断返回 false,但如果我从 VSCode 编辑器复制相同的路径,它可以完美运行。
使用 var_dump($path) 转储变量后;我注意到了一些神秘的东西。 对于我从文件资源管理器复制的路径,它显示长度为 94。 对于我从 VSCode 编辑器复制的路径,它显示长度为 88。
在我的代码编辑器中,两条路径的长度看起来相同。
我的建议:如果字符串包含隐藏字符,它可能会失败并且不起作用。