Team LiB
Previous Section Next Section

File Permissions


This section of the chapter relates only to those users who are using PHP in a Unix environment (such as Linux, FreeBSD, and the like). Those users who are running PHP from a Windows environment may safely ignore this section.

Anytime PHP works with the file system in a Unix environment, at least some knowledge of the underlying permission system is required. Without the proper permissions, PHP may have difficulty accessing directories or reading and writing files, whereas too many permissions will make both your scripts and the entire system vulnerable to hackers. This section is designed to educate you on how the file permission system works and show you how to work with the permission system from PHP.

How Unix Permissions Work

In the Unix environment, a number of factors contribute to determining what files can be accessed under what circumstances. Specifically, each file (and directory) within the file system is owned by two separate entitiesthe individual user and a group. These owners form the foundation of the rest of the Unix permission system. Before we really get into how the permission system works, consider the following entries in Listing 20.11 taken from a Unix file listing using the ls -l command from the console:

Listing 20.11. Unix Environment File Listing
drwxr-xr--   19 php      phpgroup          4096 Nov  5 20:01 php4
-rwxr--r--    1 php      phpgroup            61 Oct 31 10:52 phplogin

So what does all this information mean? Let's break down one of the file entries and describe each segment. Starting from right to left, the first entry of the listing denotes whether the entry is a directory. This can be determined by either a dash (-) if the entry is a file or a d if it is a directory (in our case, php4 is a directory and phplogin is a file). The remainder of this section determines the actual permissions given for each specific file or directory (more on that in a moment). The second piece of information (a number) represents how many levels exist for this file or directory. All entries, regardless of whether they are a directory or a file, have a value of at least 1. In the case of the php4 directory, you can see that 19 sublevels (meaning 19 additional directories) exist, whereas phplogin, being a file, has a value of 1. The third piece of information (php in both examples) is the name of the user who owns the file, and the fourth segment (phpgroup) represents the name of the group who owns the file. The final three segments represent the size of the file or directory, the date the entry was last modified, and the name of the file.

As previously mentioned, the entire Unix permission system revolves around the user and group owners of the file. Specifically, three permission groups exist (user, group, and global), each of which can be assigned three types of access individually (read, write, and execute). What permissions are assigned to which groups can be determined by the first segment of the example shown in Listing 20.10 (magnified below in Figure 20.1):

Figure 20.1. Permission Flags in a Unix directory listing.

In Figure 20.1, both the user and group have been given all three permissions (read, write, and execute), whereas all other users (global) have only read and execute permissions.

Unless you have been previously exposed to Unix permissions, it may not be clear exactly what these three permissions (read, write, and execute) mean. Because the definition of read/write/execute differs depending on whether the entry is a file or a directory, files and directories are described next.

When you're dealing with files, read and write permission allows the given user or group the capability to read and write to the file. Also as expected, the execute permission gives the affected user or group permission to execute a given file. However, with directories, the permissions take on a slightly different meaning. For a particular user or group to be able to view the directory contents for a given directory, that user or group must have been given read permission. To create or remove files in a given directory, the particular user or group must have write permission. Finally, to be able to access a particular directory at all, the user or group must have execute permission.


If a particular user or group has been given permission to write to a directory, they will be able to delete files within that directory regardless of whether they actually have write access to that file!

Now that you have been introduced to how the permission system in Unix works, let's take a look at how to adjust the permissions. The following brief discussion will be done in terms of the actual Unix commands used; see the following section on the PHP counterparts to these commands.

In Unix, three fundamental commands are used to modify the permission system: chown, chgrp, and chmod. These commands change the owner, group, and permissions, respectively. Because the focus of this book is PHP, these commands will be only briefly discussed as they relate to their corresponding PHP functions. For a complete reference on these functions, many resources exist both online and off. A good place to start is the manual pagestype man <command> from a Unix console.


For the following commands, the desired user or group must exist before chown or chgrp can be used. Furthermore, changing the owner of a file can be done only by a superuser (that is, root). If you do not have access to a superuser account, contact your system administrator.

Because they directly relate to each other, let's first take a look at the chown and chgrp functions. These functions allow you to change the owner and associated group for one or more files. The basic format for this command is as follows:

chown [OPTIONS] newowner <filespec>

Following is an example that changes the owner of the mytestfile.txt file to the user john and changes all files starting with the letter a so that they are owned by foo:

[user@localhost]# chown john mytestfile.txt
[user@localhost]# chown foo a*

Likewise, the chgrp command is used to change the group that the file belongs to and follows the same basic syntax as chown:

chgrp [OPTIONS] newgroup <filespec>

Following is an example similar to the preceding chown example, except this time the group is changed to mygroup and anothergroup, respectively:

[user@localhost]# chgrp mygroup mytestfile.txt
[user@localhost]# chgrp anothergroup a*

Because changing the user and group of a file can be done only by a superuser such as root, chances are that you will need to find alternative methods of allowing access to files. Changing the access permissions (read/write/execute) is accomplished by using the chmod command. Although there are two methods of adjusting the permissions for a file from the command line (using strings or using a base-8 numeric value), only the numeric method is available in PHP and will be the only method discussed.

All the permissions (read/write/execute) across the three permission groups (user/group/global) can be presented in a numeric form. For instance, the numeric value of the user-level read permission is 400, and the global-level read permission's value is 4. These values can then be added together to set multiple permissions:

400 (user read) + 4 (global read) = 404

The value of each permission is represented in Table 20.5:

Table 20.5. UNIX Permission Values


Owner Read


Owner Write


Owner Execute


Group Read


Group Write


Group Execute


Global Read


Global Write


Global Execute

Hence, the numeric value to give read/write/execute access to the user and read permission to both the group and globally is as follows:


Owner Read


Owner Write


Owner Execute


40Group Read


Global Read

= 744

Permission Value

To use this numeric value to apply the desired permissions to a file or files, the chmod function is used in the following manner:

chmod [OPTIONS] <permission value> <filespec>

The following example gives complete access to the file example.txt to the user and only read/execute permission to the group and globally:

[user@localhost]$ chmod 755 example.txt

Working with Permissions from PHP


When dealing with permissions in PHP, all commands that are executed will be done as the user and group that the Web server (or user, if you are running the command-line version of PHP) is running as. This is to prevent malicious users from writing scripts that compromise your system. Be very careful when granting access to the user under which your Web server/PHP runs.

In the previous section, we discussed using Unix commands to modify permission-related items for files; except for a few minor differences, these commands are available in an almost identical form as PHP functions. In this section I'll discuss how permission-related tasks, such as changing the owner or group of a file and changing the permissions granted to each permission group, are accomplished via the PHP permission functions.

As with changing the owner or member group of a file from a Unix console using the chown and chgrp commands, PHP provides similar facilities through the chown() and chgrp() functions. The syntax for both the chown() and chgrp() functions is as follows:

chown($filename, $newuser)
chgrp($filename, $newgroup)

In each $filename is a string representing the filename (complete with path if necessary) for the file to be modified, and $newuser / $newgroup is a string representing the name of the user/group to give ownership of the file to. As with the chown Unix commands, the chown() PHP function can be executed only if the Web server (or the PHP binary if running from the command line) has superuser rights. Furthermore, the chgrp() function can be used only to change the group of the file to a group that PHP belongs to. Listing 20.12 combines the chown() and chgrp() functions with the directory functions discussed earlier in the chapter to give ownership of all the files in /tmp/ to the user php and changes the member group of each to phpgroup:

Listing 20.12. Using the chown() and chgrp() Functions
     $dr = @opendir("/tmp/");
     if(!$dr) {
          echo "Error, couldn't open /tmp/!";

     while(($filename = readdir($dr)) !== false) {

          chown($filename, "php");
          chgrp($filename, "phpgroup");

As with the Unix console where chmod was used, changing the permissions for a file from PHP is accomplished via the chmod() function. The syntax for this function is as follows:

chmod($filename, $mode)

$filename represents the file to adjust the permissions for, and $mode represents the base-8 numeric value representing the permissions to set for the file (see the previous section for an explanation of numeric representations of permissions).


Note that $mode is not a decimal number (it's base 8octal). For the chmod() function to adjust the permissions of the file properly, any numbers passed to it must be represented as an octal number by prefixing it with a leading zero.

As an example of its use, the following script (Listing 20.13) attempts to open the already existing (assumed) file myfile.txt for writing. If the attempt to open the file for writing fails, the chmod() function is used in an attempt to give itself write-access to the file before failing:

Listing 20.13. Using the chmod() Function
     $fr = @fopen("myfile.txt", 'w');
     if(!$fr) {
                 chmod("myfile.txt", 0722);
                 $fr = @fopen("myfile.txt", 'w');
          if(!$fr) {
          echo "Error: Couldn't open myfile.txt (chmod attempted)";
     fputs($fr, "Write Successful!");

    Team LiB
    Previous Section Next Section