chmod
Осуществляет попытку изменения режима доступа указанного файла на режим, переданный в параметре permissions .
Список параметров
Обратите внимание, что значение параметра permissions не переводится автоматически в восьмеричную систему счисления, поэтому, чтобы удостовериться в том, что режим был установлен верно, предваряйте нулём (0) значение передаваемое в параметре permissions . Строки, такие как «g+w», не будут работать должным образом.
chmod ( «/somedir/somefile» , 755 ); // десятичное, скорее всего, указано неверно
chmod ( «/somedir/somefile» , «u+rwx,go+rx» ); // строка, неверный способ
chmod ( «/somedir/somefile» , 0755 ); // восьмеричное, верный способ
?>?php
Значение параметра permissions состоит из трёх восьмеричных чисел, определяющих уровень доступа для владельца файла, для группы, в которую входит владелец, и для других пользователей, соответственно. Число, определяющее уровень пользователя, может быть вычислено путём суммирования значений, определяющих права: 1 — доступ на выполнение, 2 — доступ на запись, 4 — доступ на чтение. Сложите эти числа для указания нужного права доступа. Более подробно о системе прав в системах Unix вы можете узнать с помощью команд ‘man 1 chmod‘ и ‘man 2 chmod‘.
// Доступ на запись и чтение для владельца, нет доступа для других
chmod ( «/somedir/somefile» , 0600 );
?php
// Доступ на запись и чтение для владельца, доступ на чтение для других
chmod ( «/somedir/somefile» , 0644 );
// Полный доступ для владельца, доступ на чтение и выполнение для других
chmod ( «/somedir/somefile» , 0755 );
// Полный доступ для владельца, доступ на чтение и выполнение для группы владельца
chmod ( «/somedir/somefile» , 0750 );
?>
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Ошибки
В случае возникновения ошибки выдаётся ошибка уровня E_WARNING .
Примечания
Замечание:
Текущим пользователем является пользователь, от имени которого выполняется PHP. Возможно, что это будет не тот пользователь, под именем которого вы получаете доступ к командной оболочке или учётной записи FTP. На большинстве систем режим доступа к файлу может быть изменён только его владельцем.
Замечание: Эта функция неприменима для работы с удалёнными файлами, поскольку файл должен быть доступен через файловую систему сервера.
Смотрите также
- chown() — Изменяет владельца файла
- chgrp() — Изменяет группу файла
- fileperms() — Возвращает информацию о правах на файл
- stat() — Возвращает информацию о файле
User Contributed Notes 17 notes
BEWARE, a couple of the examples in the comments suggest doing something like this:
chmod(file_or_dir_name, intval($mode, 8));
However, if $mode is an integer then intval( ) won’t modify it. So, this code.
$mode = 644;
chmod(‘/tmp/test’, intval($mode, 8));
. produces permissions that look like this:
Instead, use octdec( ), like this:
BEWARE using quotes around the second parameter.
php will not complain but will do an implicit conversion to an int before running chmod. Unfortunately the implicit conversion doesn’t take into account the octal string so you end up with an integer version 644, which is 1204 octal
Value Permission Level
400 Owner Read
200 Owner Write
100 Owner Execute
40 Group Read
20 Group Write
10 Group Execute
4 Global Read
2 Global Write
1 Global Execute
In the previous post, stickybit avenger writes:
Just a little hint. I was once adwised to set the ‘sticky bit’, i.e. use 1777 as chmod-value.
Note that in order to set the sticky bit on a file one must use ‘01777’ (oct) and not ‘1777’ (dec) as the parameter to chmod:
chmod ( «file» , 01777 ); // correct
chmod ( «file» , 1777 ); // incorrect, same as chmod(«file»,01023), causing no owner permissions!
?>
Rule of thumb: always prefix octal mode values with a zero.
use a stored string for the mask is a pain
ex: $mask contains a string 0755
int($mask) not work (return 755)
the only way i found is use octdec($mask)
Changes file mode recursive in $pathname to $filemode
$iterator = new RecursiveIteratorIterator (new RecursiveDirectoryIterator ( $pathname ));
foreach( $iterator as $item ) chmod ( $item , $filemode );
>
If you cannot chmod files/directories with PHP because of safe_mode restrictions, but you can use FTP to chmod them, simply use PHP’s FTP-functions (eg. ftp_chmod or ftp_site) instead. Not as efficient, but works.
Note that info at rvgate dot nl’s chmodnum function produces INCORRECT results. The resutls are base-10 numbers that only LOOK like they are octal numbers. The function also ignores setuid, setgid and sticky bits, and will produce incorrect numbers if such a file is encountered. Instead, this brute-force code works. Maybe there is something more slick, but this isn’t too CPU-intensive (note that it assumes you’ve error-checked that you indeed have a 10-character string!):
$permissions = ‘drwxr-xr-x’ ; // or whatever
$mode = 0 ;
if ( $permissions [ 1 ] == ‘r’ ) $mode += 0400 ;
if ( $permissions [ 2 ] == ‘w’ ) $mode += 0200 ;
if ( $permissions [ 3 ] == ‘x’ ) $mode += 0100 ;
else if ( $permissions [ 3 ] == ‘s’ ) $mode += 04100 ;
else if ( $permissions [ 3 ] == ‘S’ ) $mode += 04000 ;
if ( $permissions [ 4 ] == ‘r’ ) $mode += 040 ;
if ( $permissions [ 5 ] == ‘w’ ) $mode += 020 ;
if ( $permissions [ 6 ] == ‘x’ ) $mode += 010 ;
else if ( $permissions [ 6 ] == ‘s’ ) $mode += 02010 ;
else if ( $permissions [ 6 ] == ‘S’ ) $mode += 02000 ;
if ( $permissions [ 7 ] == ‘r’ ) $mode += 04 ;
if ( $permissions [ 8 ] == ‘w’ ) $mode += 02 ;
if ( $permissions [ 9 ] == ‘x’ ) $mode += 01 ;
else if ( $permissions [ 9 ] == ‘t’ ) $mode += 01001 ;
else if ( $permissions [ 9 ] == ‘T’ ) $mode += 01000 ;
printf ( ‘Mode is %d decimal and %o octal’ , $mode , $mode );
?>
Just an update of the solution with octdec. You have to give octdec the string as a parameter.
$mode = ‘644’;
chmod(file_or_dir_name, octdec($mode));
Windows has a very different file permission model to Unix and integrates them only minimally.
On Windows, all this function can do is to change the «read only» flag, which is turned on if $mode & 0200 does not pass.
i.e. it only checks if u+w is missing from the bitmask, and if it is, it sets the read only flag.
The executable flag cannot be set as Windows determines it based on file extension.
The write flag cannot be set as Windows determines write access based on ACLs, which are not integrated here.
an update to ‘neil at 11 out of 10’s code for changing mode using FTP.
changes: proper array added within the function (better for those of us who only need to connect to one ftp server) so only the mode and directory name need to be passed.
the octal added, for completeness and predictable stability.
function changemode ( $xcite )
<
$ftp_details = array(
ftp_user_name => ‘username’ ,
ftp_user_pass => ‘password’ ,
ftp_user_root => ‘/public_html/’ ,
ftp_server => ‘ftp.something.org’
);
$path = «public» ;
$mod = intval ( $xcite , 8 );
// extract ftp details (array keys as variable names)
extract ( $ftp_details );
// set up basic connection
$conn_id = ftp_connect ( $ftp_server );
// login with username and password
$login_result = ftp_login ( $conn_id , $ftp_user_name , $ftp_user_pass );
// try to chmod $path directory
if ( ftp_site ( $conn_id , ‘CHMOD ‘ . $mod . ‘ ‘ . $ftp_root . $path ) !== false ) <
$success = TRUE ;
>
else <
$success = FALSE ;
>
// close the connection
ftp_close ( $conn_id );
return $success ;
>
?>
for those of you, like me, who were looking for a way to make an ‘un-hackable’ uploader, here’s the closest i got, now for a field test, good luck!
I was trying to change permissions of a folder with chmod command with FTP connection. (I needed a writable folder to upload pictures with php)
I got the following respond:
«SITE CHMOD 777 uploads: command not understood»
The reason: Server is running under Windows system that does not allow to set file permissions via FTP. Conversely, the UNIX-running servers allow that.
1. If your web hosting provider has a web-based control panel that lets you set file permissions, then you need to login there and make changes.
2. It is possible to contact the hosting provider and ask them about this issue; maybe they can make the changes.
3. It is possible to change the hosting provider that has servers run on UNIX, and keep the site there.
I use the code of haasje@welmers.net, but have a lite alteration. (linux symlink)
function chmod_R ( $path , $filemode ) <
if (! is_dir ( $path ))
return chmod ( $path , $filemode );
$dh = opendir ( $path );
while (( $file = readdir ( $dh )) !== false ) <
if( $file != ‘.’ && $file != ‘..’ ) <
$fullpath = $path . ‘/’ . $file ;
if( is_link ( $fullpath ))
return FALSE ;
elseif(! is_dir ( $fullpath ))
if (! chmod ( $fullpath , $filemode ))
return FALSE ;
elseif(! chmod_R ( $fullpath , $filemode ))
return FALSE ;
>
>
if( chmod ( $path , $filemode ))
return TRUE ;
else
return FALSE ;
>
?>
thanks alls
error_reporting ( E_ERROR | E_PARSE );
/* Makes is so Directories are not browseable to the public,
removing only the Public = Read permission, while leaving
the other chmod permissions for the file in tact.
?php>
If you have exectue already on, and read off, public viewers will only
be able to view files through links, but not browse
around to see what’s inside of directories and see what
you’ve got laying around. */
//——————————————————-
// Get file mode
// Get file permissions supported by chmod
function getmod ( $filename ) <
$val = 0 ;
$perms = fileperms ( $filename );
// Owner; User
$val += (( $perms & 0x0100 ) ? 0x0100 : 0x0000 ); //Read
$val += (( $perms & 0x0080 ) ? 0x0080 : 0x0000 ); //Write
$val += (( $perms & 0x0040 ) ? 0x0040 : 0x0000 ); //Execute
// Misc
$val += (( $perms & 0x40000 ) ? 0x40000 : 0x0000 ); //temporary file (01000000)
$val += (( $perms & 0x80000 ) ? 0x80000 : 0x0000 ); //compressed file (02000000)
$val += (( $perms & 0x100000 ) ? 0x100000 : 0x0000 ); //sparse file (04000000)
$val += (( $perms & 0x0800 ) ? 0x0800 : 0x0000 ); //Hidden file (setuid bit) (04000)
$val += (( $perms & 0x0400 ) ? 0x0400 : 0x0000 ); //System file (setgid bit) (02000)
$val += (( $perms & 0x0200 ) ? 0x0200 : 0x0000 ); //Archive bit (sticky bit) (01000)
# User Read = 0400 (256), Write = 0200 (128), Execute = 0100 (64)
# Group Read = 0040 (32), Write = 0020 (16), Execute = 0010 (8)
# Public Read = 0004 (4), Write = 0002 (2), Execute = 0001 (1)
//——————————————————-
// Take the read option off of all the subdirectories of the included path
function pathlock ( $dir , $listall = false , $testrun = true ) <
echo «START @ » . date ( «F j, Y, h:i:s A» ) . «
» ;
echo ( $testrun ? ‘**Test Run Activated (no changes will be made).**
‘ : ‘**Live Run Activated.**
‘ );
echo $dir . » is our directory.
\n» ;
echo «[. IN PROGRESS. ]
» ;
while ( $stack ) <
$current_dir = array_pop ( $stack );
if ( $dh = opendir ( $current_dir )) <
while (( $file = readdir ( $dh )) !== false ) <
if ( $file !== ‘.’ AND $file !== ‘..’ ) <
$current_file = » < $current_dir >/ < $file >» ;
if ( is_dir ( $current_file )) <
// BEG ADD PATH
$mode = getmod ( $current_file ); //Get the mode
$HasPubRead = hasmod ( $mode , 4 );
if ( $HasPubRead || $listall ) < // Can the public read this dir?
//======================================
$ch = true ;
$take = 0 ;
// Change the mode:
if ( $HasPubRead ) <
$take = 4 ; // Value for Public Read. 4 is the same in octal and decimal.
if (! $testrun ) <
$ch = chmod ( $current_file , $mode — $take );
>
>
echo $current_file . «,current keyword»>. decoct ( $mode ) .
(( $mode !== $mode — $take ) ? «,new keyword»>. decoct ( $mode — $take ) : » ) .
( $ch ? » : ‘,FAILED’ ) . «
\n» ;
> // end if hasmod
// END ADD PATH
$stack [] = $current_file ;
> // if if_dir
> //if ($file !== ‘.’ AND $file !== ‘..’)
> //while (($file = readdir($dh)) !== false)
> //if ($dh = opendir($current_dir))
> // while ($stack)
echo «
COMPLETE @ » . date ( «F j, Y, h:i:s A» ) . «
\n» ;
return;
//return $path_list;
> // end function
//——————————————————-
//listall Show all folders, even one’s we’re not going to process?
//testrun Do a test run without making any changes
pathlock ( $_SERVER [ «DOCUMENT_ROOT» ], false , true ); // listall?=false, testrun?=true