• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • is_writable()

    (PHP 4, PHP 5, PHP 7)

    判断给定的文件名是否可写

    说明

    is_writable(string $filename): bool

    如果文件存在并且可写则返回TRUE$filename参数可以是一个允许进行是否可写检查的目录名。

    记住 PHP 也许只能以运行 webserver 的用户名(通常为'nobody')来访问文件。不计入安全模式的限制。

    参数

    $filename

    要检查的文件名称。

    返回值

    如果文件$filename存在并且可写则返回TRUE

    范例

    Example #1is_writable()例子

    <?php
    $filename = 'test.txt';
    if (is_writable($filename)) {
        echo 'The file is writable';
    } else {
        echo 'The file is not writable';
    }
    ?>
    

    错误/异常

    失败时抛出E_WARNING警告。

    注释

    Note:此函数的结果会被缓存。参见clearstatcache()以获得更多细节。

    Tip

    自 PHP 5.0.0 起,此函数也用于某些URL 包装器。请参见支持的协议和封装协议以获得支持stat()系列函数功能的包装器列表。

    参见

    Be warned, that is_writable returns false for non-existent files, although they can be written to the queried path.
    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));
        
      }
    }
    ?>
    
    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
    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
    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;
        }
      } 
    ?>
    
    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
    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;
    ?>
    
    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.'
    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;
      
    }
    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;
    }
    ?>
    
    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
    function is_writable('ftp://user.....') always return false. I can create/delete files, but can check is writable. Is this bug or php feature :)?
    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.
    Under Windows, it only returns the read-only attribute status, not the actual permissions (ACL).
    See http://bugs.php.net/bug.php?id=27609