Be warned, that is_writable returns false for non-existent files, although they can be written to the queried path.
(PHP 4, PHP 5, PHP 7, PHP 8)
is_writable — Indique si un fichier est accessible en écriture
retourne true
si filename
existe et est
accessible en écriture. L'argument peut être le nom d'un dossier,
vous permettant ainsi de vérifier si le dossier est accessible
en écriture.
N'oubliez pas que PHP accède aux fichiers avec les mêmes
autorisations que l'utilisateur qui fait tourner le serveur web
(souvent, c'est 'nobody
', personne).
filename
Le nom du fichier à vérifier.
Retourne true
si le fichier filename
existe et est accessible en écriture.
En cas d'échec, une alerte de type E_WARNING
sera émise.
Exemple #1 Exemple avec is_writable()
<?php
$filename = 'test.txt';
if (is_writable($filename)) {
echo 'Le fichier est accessible en écriture.';
} else {
echo 'Le fichier n\'est pas accessible en écriture !';
}
?>
Note: Les résultats de cette fonction sont mis en cache. Voyez la fonction clearstatcache() pour plus de détails.
À partir de PHP 5.0.0, cette fonction peut aussi être utilisée avec quelques protocoles url. Lisez Liste des protocoles et des gestionnaires supportés pour connaître les protocoles supportant la famille de fonctionnalités de stat().
Be warned, that is_writable returns false for non-existent files, although they can be written to the queried path.
In Linux, you might encountering an issue which is a file is not writable even tho it has 644 permission! The problem is with SELinux, just disable it or add rules to allow it.
To Darek and F Dot: About group permissions, there is this note in the php.ini file:
; By default, Safe Mode does a UID compare check when
; opening files. If you want to relax this to a GID compare,
; then turn on safe_mode_gid.
safe_mode_gid = Off
Check director is writable recursively. to return true, all of directory contents must be writable
<?php
function is_writable_r($dir) {
if (is_dir($dir)) {
if(is_writable($dir)){
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (!is_writable_r($dir."/".$object)) return false;
else continue;
}
}
return true;
}else{
return false;
}
}else if(file_exists($dir)){
return (is_writable($dir));
}
}
?>
It appears that is_writable() does not check full permissions of a file to determine whether the current user can write to it. For example, with Apache running as user 'www', and a member of the group 'wheel', is_writable() returns false on a file like
-rwxrwxr-x root wheel /etc/some.file
Regarding you might recognize your files on your web contructed by your PHP-scripts are grouped as NOBODY you can avoid this problem by setting up an FTP-Connection ("ftp_connect", "ftp_raw", etc.) and use methods like "ftp_fput" to create these [instead of giving out rights so you can use the usual "unsecure" way]. This will give the files created not the GROUP NOBODY - it will give out the GROUP your FTP-Connection via your FTP-Program uses, too.
Furthermore you might want to hash the password for the FTP-Connection - then check out:
http://dev.mysql.com/doc/mysql/en/Password_hashing.html
This file_write() function will give $filename the write permission before writing $content to it.
Note that many servers do not allow file permissions to be changed by the PHP user.
<?php
function file_write($filename, &$content) {
if (!is_writable($filename)) {
if (!chmod($filename, 0666)) {
echo "Cannot change the mode of file ($filename)";
exit;
};
}
if (!$fp = @fopen($filename, "w")) {
echo "Cannot open file ($filename)";
exit;
}
if (fwrite($fp, $content) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
if (!fclose($fp)) {
echo "Cannot close file ($filename)";
exit;
}
}
?>
The results of this function seems to be not cached :
Tested on linux and windows
<?php
chmod($s_pathFichier, 0400);
echo'<pre>';var_dump(is_writable($s_pathFichier));echo'</pre>';
chmod($s_pathFichier, 04600);
echo'<pre>';var_dump(is_writable($s_pathFichier));echo'</pre>';
exit;
?>
This function returns always false on windows, when you check an network drive.
See PHP Bug https://bugs.php.net/bug.php?id=68926
See https://stackoverflow.com/q/54904676