Working with Permissions in PHP, Part 2In my last column, we took a step away from PHP to discuss the Unix permissions system. In today's column we return to PHP to show you how to apply what you learned last time; again, this column applies only to those who work with PHP in an environment that supports Unix-like permission.
Before I begin to discuss the PHP permission functions, I will explain
some common permission-related problems which occur with PHP scripts. Like
all applications in a Unix environment, PHP programs are run on behalf of
a particular user. If a PHP script is executed from the command line (for
instance, as a shell script), it will run with the permissions of the user
who started the script. For web servers, however, your PHP scripts run as
the same user as the web server runs as. Under most system configurations,
web servers run as the user nobody, which has minimal
permissions to access the file system.
Although it can be more difficult to work under this situation at times, it's strongly recommended that PHP never be ran via a web server in any other manner for security reasons. A much more reasonable solution is to create directories where PHP will be accessing files and assign it to the same group to which the PHP script belongs.
|
Also in PHP Foundations: |
In my last column, I discussed three separate commands to manipulate
Unix file permissions. The first of these commands was chown,
which had to be run by a super-user (such as root) and
changes the owner of a file. The second command, chgrp,
changes the group to which a particular file belongs, as long as the user
running chgrp is a member of the new group. Finally, the
last command is chmod, which allows any user to modify the
permissions of a file owned by the user.
In PHP, these three commands (chown, chgrp,
and chmod) have almost direct counterparts in the form of PHP
functions. For instance, where Unix has the chown command,
PHP has a chown() function with the following syntax:
chown($filename, $newuser)
$filename refers to the file that is being modified, and
$newuser is the username of the new owner. When executed this
function returns a boolean value which indicates whether PHP was
successful in changing the owner of the file. As with the Unix
chown command, the chown() function cannot be
successfully executed by a script unless the script is running with
super-user privileges.
Like the chown command, the chgrp command
also has a counterpart in the chgrp() PHP function. Their
syntax is almost identical:
chgrp($filename, $newgroup)
The $filename parameter is the file to modify and
$newgroup is the name of the group to make the file a member
of. This function also returns a boolean value indicating the success or
failure of the group change. Unlike chown(), the
chgrp() function can be used to change the group of a file as
long as the group that PHP belongs to is also a member of that group.
The following script, which illustrates the use of these functions,
brings together the
PHP directory object discussed in a previous article with today's
discussion. It attempts to change the owner of all the files in the
/tmp/ directory to php and the group of all of
the files to phpgroup:
<?php
$dir = dir("/tmp/");
while(($file = $dir->read()) !== false) {
chown($filename, "php");
chgrp($filename, "phpgroup");
}
$dir->close();
?>
The third and final command is chmod. chmod
sets the permission values for the three permission levels (user, group,
and global) via a numeric value representing the desired permissions. A
complete list of the permissions, their associated numeric values, and
their use, can be found in my last column. In
PHP, changing permission values for a file is done through the
chmod() function with the following syntax:
chmod($filename, $permissions)
Again, $filename represents the file to modify and
$permissions represents the new permission value. These
numbers are not standard decimal values. The Unix permission system is
based on numeric values rooted in base 8 (octal) rather than the standard
decimal base 10. Hence, when passing a value to $permissions
it is necessary to prefix a leading zero to the value to mark it as an
octal value. To demonstrate this function in a more practical
application, the following short script attempts to open a file for
reading. If the initial attempt to open the file for reading fails, PHP
will attempt to modify the permissions of the file and open the file
again:
<?php
$fr = fopen("myfile.txt", 'r');
if(!$fr) {
/* Must be 0444 (octal), NOT just 444 */
if(!chmod("myfile.txt", 0444)) {
echo "Error -- couldn't open myfile.txt for reading!";
exit;
} else {
$fr = fopen("myfile.txt", 'r');
}
}
$myvalue = fgets($fr, 1024);
fclose($fr);
?>
As should be obvious from this short program, because the three system calls demonstrated here all return a value indicating their success or failure, these results should always be checked. Assuming that system calls always succeed is a recipe for disaster.
There is much more to permissions and the file system than can be discussed here. If you have questions, consult the PHP Manual. In my next column I'll be taking a look into working with form data from PHP.
John Coggeshall is a a PHP consultant and author who started losing sleep over PHP around five years ago.
Read more PHP Foundations columns.
Return to the PHP DevCenter.
Copyright © 2007 O'Reilly Media, Inc.