PHP 日本大会 2024

is_writable

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

is_writable判断文件名是否可写

描述

is_writable(string $filename): bool

如果 filename 存在且可写,则返回 true。文件名参数可以是目录名,允许您检查目录是否可写。

请记住,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() 系列的功能。

参见

添加备注

用户贡献的备注 15 条备注

helvete at bahno dot net
7 年前
请注意,对于不存在的文件,is_writable 返回 false,尽管可以写入查询的路径。
starrychloe at yahoo dot com
16 年前
对于 Darek 和 F Dot:关于组权限,php.ini 文件中有以下说明
; 默认情况下,安全模式在
; 打开文件时执行 UID 比较检查。如果您想将其放宽为 GID 比较,
; 那么请启用 safe_mode_gid。
safe_mode_gid = Off
arikan134 at gmail dot com
8 年前
递归检查目录是否可写。要返回 true,所有目录内容都必须可写

<?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));

}
}

?>
darek at fauxaddress dot com
18 年前
看起来 is_writable() 不会检查文件的完整权限以确定当前用户是否可以写入它。例如,Apache 以用户“www”运行,并且是“wheel”组的成员,is_writable() 在类似这样的文件上返回 false:

-rwxrwxr-x root wheel /etc/some.file
JimmyNighthawk
19 年前
关于您可能认识到您的 PHP 脚本构建的 Web 文件被分组为 NOBODY,您可以通过设置 FTP 连接(“ftp_connect”、“ftp_raw”等)并使用方法如“ftp_fput”来创建这些文件[而不是授予权限以便您可以使用通常的“不安全”方式]来避免此问题。这将使创建的文件不会获得 NOBODY 组 - 它也会获得 FTP 程序使用的 FTP 连接使用的组。

此外,您可能希望散列 FTP 连接的密码 - 然后查看
https://dev.mysqlserver.cn/doc/mysql/en/Password_hashing.html
agrenier at assertex dot com
20 年前
此 file_write() 函数将在将 $content 写入它之前为 $filename 赋予写权限。

请注意,许多服务器不允许 PHP 用户更改文件权限。

<?php
function file_write($filename, &$content) {
if (!
is_writable($filename)) {
if (!
chmod($filename, 0666)) {
echo
"无法更改文件模式 ($filename)";
exit;
};
}
if (!
$fp = @fopen($filename, "w")) {
echo
"无法打开文件 ($filename)";
exit;
}
if (
fwrite($fp, $content) === FALSE) {
echo
"无法写入文件 ($filename)";
exit;
}
if (!
fclose($fp)) {
echo
"无法关闭文件 ($filename)";
exit;
}
}
?>
gr
14 年前
此函数的结果似乎未被缓存
在 Linux 和 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;
?>
h3ssan at protonmail dot com
2 个月前
在 Linux 中,您可能会遇到一个问题,即即使文件具有 644 权限,它也无法写入!问题在于 SELinux,只需禁用它或添加规则以允许它。
radon-software.net 开发人员
2年前
在 Windows 系统下,检查网络驱动器时,此函数始终返回 false。

参见 PHP Bug https://bugs.php.net/bug.php?id=68926
参见 https://stackoverflow.com/q/54904676
[email protected]
18 年前
回复 Darek

我们有两台服务器:一台运行 PHP 5.0.4 和 Apache 1.3.33,另一台运行 PHP 4.3.5 和 Apache 1.3.27。PHP 4 服务器表现出您描述的行为,`is_writable()` 返回 'false',即使 www 用户属于拥有该文件的组,但 PHP 5 服务器返回 'true'。
legolas558.users.sf.net
17年前
这是我能想到的最新版本的 `is__writable()`。
它可以接受文件或文件夹,但是文件夹应该以尾部斜杠结尾!该函数尝试实际写入文件,因此当用户具有对它的ACL写访问权限时,它将正确返回 true。

<?php
function is__writable($path) {
// 将在 Windows ACLs bug 情况下工作
// 注意:文件夹需使用尾部斜杠!!!
//参见 http://bugs.php.net/bug.php?id=27609
//参见 http://bugs.php.net/bug.php?id=30931

if ($path{strlen($path)-1}=='/') // 递归返回临时文件路径
return is__writable($path.uniqid(mt_rand()).'.tmp');
else if (
is_dir($path))
return
is__writable($path.'/'.uniqid(mt_rand()).'.tmp');
// 检查临时文件的读写权限
$rm = file_exists($path);
$f = @fopen($path, 'a');
if (
$f===false)
return
false;
fclose($f);
if (!
$rm)
unlink($path);
return
true;
}
?>
legolas558.sourceforge.net
18 年前
由于看起来 Windows ACLs bug “不会修复”(参见 http://bugs.php.net/bug.php?id=27609),我建议使用此替代函数

<?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;
}

?>

它应该在 *nix 和 Windows 系统上都能工作

注意:必须使用尾部斜杠来标识目录
[email protected]
9年前
我还想就此澄清一点。即使您看到目录的权限为 777,您也可能需要检查您的 ACL,因为您的服务器组可能在那里没有写权限。
[email protected]
10年前
检查目录是否可写。也可用于已挂载的 SMB 共享。

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;

}
[email protected]
20 年前
在 Windows 下,它只返回只读属性状态,而不是实际权限 (ACL)。
参见 http://bugs.php.net/bug.php?id=27609
To Top