PHP Conference Japan 2024

is_writable

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

is_writable判斷檔案是否可寫入

描述

is_writable(字串 $filename): 布林值

如果 filename 存在且可寫入,則返回 true。filename 參數可以是目錄名稱,允許您檢查目錄是否可寫入。

請記住,PHP 可能以網路伺服器執行的使用者 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
函式 is_writable_r($dir) {
如果 (
is_dir($dir)) {
如果(
is_writable($dir)){
$objects = scandir($dir);
foreach (
$objects as $object) {
如果 (
$object != "." && $object != "..") {
如果 (!
is_writable_r($dir."/".$object)) 返回 false;
否則 continue;
}
}
返回
true;
}否則{
返回
false;
}

}否則如果(
file_exists($dir)){
返回 (
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 腳本在您的網站上建立的檔案被歸類為 NOBODY 群組,您可以透過設定 FTP 連線("ftp_connect", "ftp_raw" 等)並使用像是 "ftp_fput" 的方法來建立這些檔案 [而不是直接賦予權限,這樣您就可以使用一般的「不安全」方法] 來避免這個問題。這將使建立的檔案不會被歸類到 NOBODY 群組,而是會被歸類到您的 FTP 連線透過 FTP 程式所使用的群組。

此外,您可能需要將 FTP 連線的密碼雜湊,那麼請參考
https://mysqldev.dev.org.tw/doc/mysql/en/Password_hashing.html
agrenier at assertex dot com
20 年前
這個 file_write() 函式會在將 $content 寫入 $filename 之前,賦予 $filename 寫入權限。

請注意,許多伺服器不允許 PHP 使用者更改檔案權限。

<?php
函式 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 上,只需將其停用或新增規則以允許它即可。
develop at radon-software dot net
2 年前
當您檢查網路磁碟機時,此函式在 Windows 上始終返回 false。

參見 PHP Bug https://bugs.php.net/bug.php?id=68926
參見 https://stackoverflow.com/q/54904676
greg at gregwhitescarver dotcalm
18 年前
回覆 Darek

我們有兩台伺服器:一台執行 PHP 5.0.4 和 Apache 1.3.33,另一台執行 PHP 4.3.5 和 Apache 1.3.27。PHP 4 伺服器會出現您所描述的行為,即使 www 使用者位於擁有檔案的群組中,`is_writable()` 仍會返回 'false',但 PHP 5 伺服器會返回 'true'。
legolas558 d0t users dot sf dot net
17 年前
這是我能想到的最新版 `is_writable()`。
它可以接受檔案或資料夾,但資料夾應以斜線結尾!該函式會嘗試實際寫入檔案,因此當使用者具有 ACL 寫入權限時,它會正確地返回 true。

<?php
function is__writable($path) {
//即使 Windows ACLs 有錯誤也能運作
//注意:資料夾路徑必須加上結尾斜線!!!
//參考 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 dot sourceforge comma net
18 年前
由於 Windows ACLs 的錯誤似乎「不會修復」(參見 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 系統上都能正常運作。

注意:您必須使用結尾斜線來識別目錄。
shkkmo at gmail dot com
9 年前
我還想澄清一點。即使您看到目錄的權限是 777,您也可能需要檢查您的 ACL,因為您的伺服器的群組可能沒有該目錄的寫入權限。
samuel dot zallocco at univaq dot it
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;

}
claude dot paroz at ne dot ch
20 年前
在 Windows 下,它只會傳回唯讀屬性狀態,而不是實際的權限 (ACL)。
請參閱 http://bugs.php.net/bug.php?id=27609
To Top