We help IT Professionals succeed at work.

Why is Linux execute bit needed for PHP's file_exists() function to work properly

RegProctor asked
This question is for my understanding, I can live with they way things are, but, if I could change it that would be even better.

Here's the issue: when file_exists() is used in PHP running under Apache, the function will not return TRUE as it should unless the file has the group execute bit set. This doesn't make sense to me because I thought the execute bit was only need for files that were to be executed. A file being examined by an executing piece of code should read just as long as the read bit is set as far as I know.

A little more information:
    The file is a .png, e.g.: image.png.
    The distro is OpenSUSE 11.4
    PHP is version 5.3.8
    Apache version is 2.2.17
    The permissions and owner of the file being read are:  754 reg:web-dev
    Apache is running as user wwwrun:www. It has the group web-dev added to it as well.
    If the file's permissions are 744 PHP's file_exists() will always return FALSE
    If the file's permissions are 754 PHP's file_exists() will return TRUE to show that file exists (as it should)

The annoying part about this is that there are many PHP files that are actually being executed but they don't need more than 644 to execute so why would file_exists() suddenly need the group execute bit as well (654 or 754).

A second part to this question is, is this something that could be changed somehow? I.e., make it so only the read bit is required. Then more reasonable permissions for an image could used like 644 or even 640.
Watch Question

Are you using safe_mode? Not documented exacly as your experience, but worth a try to set it to false.

How exactly are you calling this function?  Because in my experience, it does not operate this way.  Take the following code where I manually created empty files foo (mode 744) and bar (mode 754).  I purposely didn't create file baz.

xterm@dellxps:~/Documents/ee$ ./fe.php
File foo exists
-rwxr-xr-- 1 xterm xterm 0 2011-12-06 02:24 foo
File bar exists
-rwxr--r-- 1 xterm xterm 0 2011-12-06 02:24 bar
File baz doesn't exist



for ($i=0; $i<count($files); $i++) {
        if(file_exists($files[$i])) {
                echo "File $files[$i] exists\n";
                system("ls -l $files[$i]");
        } else {
                echo "File $files[$i] doesn't exist\n";


Open in new window


@Blaz  I checked, it looks like safe mode is off.

@xterm  You can't really get it wrong "if (file_exists('someFile')) ...", I doubt it's a php issue. The reason I gave all the info. on users. groups and permissions is because I am sure it's a Linux setup issue in some way. Linux has a myriad of things you can do with it and I am sure this is just some quirk I need to learn about.
Well, if they are truly 744 and 754, both files are still world-readable, so the owner/group doesn't matter.  My guess is that the two files are in different directories, one of which is unreadable.  Remember, if Apache doesn't have a permission to descend into a directory, it doesn't matter what the file perms in there are - they won't be visible.


I am only talking about one file, not two different files. I changed the permissions on the one file and tested the results. It's not a matter of a different directory or something like that. I have been administering my own Linux boxes for several years so a simple obvious issue like that I have already ruled out.
Here's what I found out. Some commands in PHP require the execution bit to be set in the permissions. So, regardless of the exact answer to my question, I should set the bit just so I don't get "stuck" sometime when some command runs on those files that definitely does need that bit.

It's not a perfect answer but it's good enough as it's certainly not worth tracking down any further.


It's the closest we have to an answer.