PHP Conference Nagoya 2025

is_writable

(PHP 4, PHP 5, PHP 7, PHP 8)

is_writableファイルが書き込み可能かどうかを調べる

説明

is_writable(string $filename): bool

filenameが存在して、かつそれが書き込み可能であれば trueを返します。引数filenameはディレクトリ名とすることができ、 ディレクトリが書き込み可能であることを調べることが可能です。

PHP は、Web サーバーが実行されているユーザー ID('nobody' が多い) でファイルにアクセスすることを覚えておいてください。

パラメータ

filename

調べたいファイル名。

戻り値

filename が存在して書き込み可能な場合に true を返します。

エラー / 例外

失敗したときは E_WARNING が発生します。

例1 is_writable() の例

<?php
$filename
= 'test.txt';
if (
is_writable($filename)) {
echo
'このファイルは書き込み可能です';
} else {
echo
'このファイルは書き込みできません';
}
?>

注意

注意: この関数の結果は キャッシュされます。詳細は、clearstatcache() を参照してください。

ヒント

PHP 5.0.0 以降、この関数は、 何らかの URL ラッパーと組合せて使用することができます。 どのラッパーが stat() ファミリーをサポートしているかを調べるには サポートするプロトコル/ラッパー を参照してください。

参考

  • is_readable() - ファイルが存在し、読み込み可能であるかどうかを知る
  • file_exists() - ファイルまたはディレクトリが存在するかどうか調べる
  • fwrite() - バイナリセーフなファイル書き込み処理

add a note

User Contributed Notes 15 notes

up
22
helvete at bahno dot net
7 years ago
Be warned, that is_writable returns false for non-existent files, although they can be written to the queried path.
up
8
starrychloe at yahoo dot com
16 years ago
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
up
5
arikan134 at gmail dot com
8 years ago
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));

}
}

?>
up
8
darek at fauxaddress dot com
18 years ago
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
up
2
JimmyNighthawk
19 years ago
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
up
4
agrenier at assertex dot com
20 years ago
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;
}
}
?>
up
2
gr
14 years ago
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;
?>
up
1
h3ssan at protonmail dot com
1 month ago
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.
up
1
develop at radon-software dot net
2 years ago
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
up
0
greg at gregwhitescarver dotcalm
18 years ago
In response to Darek:

We have two servers: one running PHP 5.0.4 and Apache 1.3.33, the other running PHP 4.3.5 and Apache 1.3.27. The PHP 4 server exhibits the behavior you are describing, with is_writable() returning 'false' even though the www user is in the group that owns the file, but the PHP 5 server is returning 'true.'
up
-1
legolas558 d0t users dot sf dot net
17 years ago
This is the latest version of is__writable() I could come up with.
It can accept files or folders, but folders should end with a trailing slash! The function attempts to actually write a file, so it will correctly return true when a file/folder can be written to when the user has ACL write access to it.

<?php
function is__writable($path) {
//will work in despite of Windows ACLs bug
//NOTE: use a trailing slash for folders!!!
//see http://bugs.php.net/bug.php?id=27609
//see http://bugs.php.net/bug.php?id=30931

if ($path{strlen($path)-1}=='/') // recursively return a temporary file path
return is__writable($path.uniqid(mt_rand()).'.tmp');
else if (
is_dir($path))
return
is__writable($path.'/'.uniqid(mt_rand()).'.tmp');
// check tmp file for read/write capabilities
$rm = file_exists($path);
$f = @fopen($path, 'a');
if (
$f===false)
return
false;
fclose($f);
if (!
$rm)
unlink($path);
return
true;
}
?>
up
-3
legolas558 dot sourceforge comma net
18 years ago
Since looks like the Windows ACLs bug "wont fix" (see http://bugs.php.net/bug.php?id=27609) I propose this alternative function:

<?php

function is__writable($path) {

if (
$path{strlen($path)-1}=='/')
return
is__writable($path.uniqid(mt_rand()).'.tmp');

if (
file_exists($path)) {
if (!(
$f = @fopen($path, 'r+')))
return
false;
fclose($f);
return
true;
}

if (!(
$f = @fopen($path, 'w')))
return
false;
fclose($f);
unlink($path);
return
true;
}

?>

It should work both on *nix and Windows

NOTE: you must use a trailing slash to identify a directory
up
-3
shkkmo at gmail dot com
9 years ago
I'd like to also clarify a point on this. Even if you see 777 permissions for the directly, you may need to check your ACL, since your server's group might not have write permissions there.
up
-3
samuel dot zallocco at univaq dot it
10 years ago
Check if a directory is writable. Work also on mounted SMB shares:

function isWritablePath($home, $xpath) {
$isOK = false;
$path = trim($xpath);
if ( ($path!="") && (strpos($path,$home)!==false) && is_dir($path) && is_writable($path) ) {
$tmpfile = "mPC_".uniqid(mt_rand()).'.writable';
$fullpathname = str_replace('//','/',$path."/".$tmpfile);
$fp = @fopen($fullpathname,"w");
if ($fp !== false) {
$isOK = true;
}
@fclose($fp);
@unlink($fullpathname);
}
return $isOK;

}
up
-5
claude dot paroz at ne dot ch
20 years ago
Under Windows, it only returns the read-only attribute status, not the actual permissions (ACL).
See http://bugs.php.net/bug.php?id=27609
To Top