PHP mkdir() and fopen() does not work - permissions problem? umask problem?

matthewpavkov picture matthewpavkov · Oct 31, 2010 · Viewed 12k times · Source

The following PHP script fails to create the directory. It will also fail to create the file (when the directory already exists).

ini_set('error_reporting', E_ALL);

define('ABSPATH', $_SERVER['DOCUMENT_ROOT']);
echo ABSPATH . '<br /><br />';

$dir_to_make = ABSPATH . '/aaatest';
$file_to_make = ABSPATH . '/aaatest/aaatest.txt';

echo umask() . '<br />';

mkdir($dir_to_make) or die('could not create directory');
fopen($file_to_make) or die('could not open/create file');

The umask() is returning a value of 18. The document root has a period in it ( /var/www/blah/websitename.com/httpdocs ).

I don't completely understand umask(), nor am I sure of how to properly use it. I don't know if that's the problem or not, but it does seem to be likely. Should I change the umask, create the file/directory, then change it back? What should the umask be to change/make/edit files/directories? Should the server be configured differently?

Answer

Lee picture Lee · Oct 31, 2010

In order to create a file within the document root, your PHP process must have permissions to write to the directory. Usually (but not always) PHP runs as the same user that the web server runs as. The name of this user will vary with different systems. On Ubuntu and Debian, the user is called www-data, on other systems it may be just www, or apache, or apache2. On some systems, it may be root.

You can find out what user your PHP runs as by examining the value of the server superglobal: $_SERVER['USER']. phpinfo() provides an easy way look at stuff like this. Usually, the PHP user is the same as the web server user (but not always).

setting directory ownership and permissions is another topic entirely - depends on what operating system you're on, what access and permissions you have for the server, and lots of other stuff. If you need pointers on this, you might start at serverfault.com.

good luck.


[edit] OK, if you're runing as apache, and you're trying to create your new directory in /var/www/blah/mydomain.com/htdocs/... then when you run:

> ls -splad /var/www/blah/mydomain.com/htdocs

you'd expect to see something like:

4 drwxr-xr-x 2 apache apache 4096 2010-07-22 20:54 /var/www/blah/mydomain.com/htdocs/

there are two interesting parts:

drwxr-xr-x means: d = directory; rwx = user has Read,Write,eXecute; r-x = group has only Read, and eXecute; r-x = everyone has only Read, and eXecute.

and apache apache - the first one is the name of the user that owns the file/directory, the second one is the name of the group that owns the file/directory.

so if you saw something like this:

4 drwxr-xr-x 2 root apache 4096 2010-07-22 20:54 /var/www/blah/mydomain.com/htdocs/

it would not work because the directory is owned by root (not apache), and even though it's grouped by apache, the directory isn't group-writeable so that doesn't cut it. In this scenario, you could simply add group write perms (chmod g+w /var/www/blah/mydomain.com/htdocs), and you're good to go.

Something else you might see is:

4 drw-r-xr-x 2 apache apache 4096 2010-07-22 20:54 /var/www/blah/mydomain.com/htdocs/

In this case, the ownership is ok, but the directory isn't writeable by its owner. You can fix this by adding write permission for the owner chmod u+w /var/www/blah/mydomain.com/htdocs.

there are lots of other variations, but maybe this will help.