PHP:is_file()和file_exists()在同一文件上返回不同的结果

3
我遇到了一个问题,file_exists返回false,而is_file返回true。
echo(getmygid()." = gid\n"); //501
echo(getmyuid()." = uid\n"); //501
echo(posix_getgid()." = pgid\n"); //501
echo(posix_getuid()." = puid\n"); //501
var_dump(file_exists("/home/www/public_html/")); //bool(true)
var_dump(file_exists("/home/www/public_html/index.html")); //bool(false)
var_dump(is_file("/home/www/public_html/index.html")); //bool(true)

var_dump(stat("/home/www/public_html/index.php")); 

输出结果为:
501 = gid
501 = uid
501 = pgid
501 = puid
bool(true)
bool(false)
bool(true)
array(26) {
  [0]=>
  int(51712)
  [1]=>
  int(58055)
  [2]=>
  int(33197)
  [3]=>
  int(1)
  [4]=>
  int(501)
  [5]=>
  int(501)
  [6]=>
  int(0)
  [7]=>
  int(473)
  [8]=>
  int(1323573973)
  [9]=>
  int(1323573973)
  [10]=>
  int(1323574039)
  [11]=>
  int(4096)
  [12]=>
  int(8)
  ["dev"]=>
  int(51712)
  ["ino"]=>
  int(58055)
  ["mode"]=>
  int(33197)
  ["nlink"]=>
  int(1)
  ["uid"]=>
  int(501)
  ["gid"]=>
  int(501)
  ["rdev"]=>
  int(0)
  ["size"]=>
  int(473)
  ["atime"]=>
  int(1323573973)
  ["mtime"]=>
  int(1323573973)
  ["ctime"]=>
  int(1323574039)
  ["blksize"]=>
  int(4096)
  ["blocks"]=>
  int(8)
}

我想我在配置方面做错了什么,但还没有完全弄清楚是什么。

更加令人兴奋的是,尽管file_exists无法工作,fread(fopen('/home/www/public_html/index.html','r'), filesize('/home/www/public_html/index.html'))确实返回文件的内容。


2
你把状态发布到了错误的文件中,请你纠正一下? - ajreal
所有这些目录(home、www、public_html)是否为此脚本启用了读取权限?它们都是目录,而不是符号链接吗? - Dalibor Filus
是的,我的错。刚刚修复了。这是它为空的状态,并使用了 655 模式。 - teotwawki
家目录是 766,www 是 drwxrwxr-x,public_html 是 drw-r-xr-x。 - teotwawki
当然。不幸的是,无论是php还是html甚至再加一个目录级别都没有太大区别。但是为了提供最完整的信息,我很快会更改这些信息。 - teotwawki
显示剩余3条评论
2个回答

2

参见file_exists()的警告:

由于安全模式限制而无法访问的文件,此函数将返回FALSE。但是如果这些文件位于 safe_mode_include_dir 中,则仍然可以被包含。

is_file() 函数似乎没有这个限制。


2
奇怪,这里有几个选项可以从手册中检查:
Note: The results of this function are cached. See clearstatcache() for more details.
或者可能是这个:
Warning

This function returns FALSE for files inaccessible due to safe mode restrictions. However these files still can be included if they are located in safe_mode_include_dir.

我能想到的唯一可能影响它的事情就是这些了。不确定你是否尝试过,但值得一试。

更新

文件标志如何?从shell(如果你有shell访问权限)可以执行ls -alh /home/www/public_html | grep index.html,确保没有奇怪的标志设置在上面吗?

更新2

问题在于目录权限被设置为所有者无法查看目录内容。在评论中进一步解释了这个问题。


根据phpinfo(),safe_mode已关闭。clearstatcache()未改变结果。 - teotwawki
正确,这不是符号链接。 - teotwawki
文件标志如何?如果您有shell访问权限,可以执行ls -alh /home/www/public_html | grep index.html命令,并确保没有设置奇怪的标志。 - Jim
我已经尝试了83886 -rwxrwxrwx 1 www www 2.6K等等,它是777,但我也尝试了766和655。 - teotwawki
Brad,我终于搞定了!虽然我不确定我完全理解为什么会这样,但希望你能帮忙。public_html目录的权限是drw-r-xr-x,但所有者需要x权限才能让file_exists在其内容上工作。所以现在public_html目录有了drwxr-xr-x,一切都正常工作了。我还有一个问题,也许你可以帮忙解答:用户“www”也是“www”组的一部分,文件的所有者和组也是“www”,那么为什么使用这些权限所有者不能查看目录内容呢? - teotwawki
这解释了这个问题。原因是,我不是文件专家,但你不能打开一个权限小于0755的目录。如果你将一个目录的权限设置为0644,你会得到一个权限被拒绝的错误。所以没错,这很有道理,我想只有root用户可以访问它,而其他人则不能。 - Jim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接