set permissions for all files and folders recursively

57,449

Solution 1

Why don't use find tool for this?

exec ("find /path/to/folder -type d -exec chmod 0750 {} +");
exec ("find /path/to/folder -type f -exec chmod 0644 {} +");

Solution 2

My solution will change all files and folder recursively to 0777. I use DirecotryIterator, it's much cleaner instead of opendir and while loop.

function chmod_r($path) {
    $dir = new DirectoryIterator($path);
    foreach ($dir as $item) {
        chmod($item->getPathname(), 0777);
        if ($item->isDir() && !$item->isDot()) {
            chmod_r($item->getPathname());
        }
    }
}

Solution 3

This is tested and works like a charm:

<?

  header('Content-Type: text/plain');

  /**
  * Changes permissions on files and directories within $dir and dives recursively
  * into found subdirectories.
  */
  function chmod_r($dir, $dirPermissions, $filePermissions) {
      $dp = opendir($dir);
       while($file = readdir($dp)) {
         if (($file == ".") || ($file == ".."))
            continue;

        $fullPath = $dir."/".$file;

         if(is_dir($fullPath)) {
            echo('DIR:' . $fullPath . "\n");
            chmod($fullPath, $dirPermissions);
            chmod_r($fullPath, $dirPermissions, $filePermissions);
         } else {
            echo('FILE:' . $fullPath . "\n");
            chmod($fullPath, $filePermissions);
         }

       }
     closedir($dp);
  }

  chmod_r(dirname(__FILE__), 0755, 0755);
?>

Solution 4

I think yours won't go recursive in case of folders, I fixed this case.

function chmod_r($Path) {
    $dp = opendir($Path);
     while($File = readdir($dp)) {
       if($File != "." AND $File != "..") {
         if(is_dir($File)){
            chmod($File, 0750);
            chmod_r($Path."/".$File);
         }else{
             chmod($Path."/".$File, 0644);
         }
       }
     }
   closedir($dp);
}

Solution 5

Here improved version of the recursive chmod that skips files with the same permissions.

<?

header('Content-Type: text/plain');

/**
* Changes permissions on files and directories within $dir and dives recursively
* into found subdirectories.
*/
function chmod_r($dir)
{
    $dp = opendir($dir);
    while($file = readdir($dp))
    {
        if (($file == ".") || ($file == "..")) continue;

        $path = $dir . "/" . $file;
        $is_dir = is_dir($path);

        set_perms($path, $is_dir);
        if($is_dir) chmod_r($path);
    }
    closedir($dp);
}

function set_perms($file, $is_dir)
{
    $perm = substr(sprintf("%o", fileperms($file)), -4);
    $dirPermissions = "0750";
    $filePermissions = "0644";

    if($is_dir && $perm != $dirPermissions)
    {
        echo("Dir: " . $file . "\n");
        chmod($file, octdec($dirPermissions));
    }
    else if(!$is_dir && $perm != $filePermissions)
    {
        echo("File: " . $file . "\n");
        chmod($file, octdec($filePermissions));
    }

    flush();
}

chmod_r(dirname(__FILE__));
Share:
57,449

Related videos on Youtube

testing
Author by

testing

Updated on February 13, 2020

Comments

  • testing
    testing over 4 years

    I want to recursively set the folder and file permissions. Folders should get 750 and files 644. I found this and made some adaptions. Would this one work?

    <?php
    
    function chmod_r($Path) {
       $dp = opendir($Path);
       while($File = readdir($dp)) {
          if($File != "." AND $File != "..") {
             if(is_dir($File)){
                chmod($File, 0750);
             }else{
                 chmod($Path."/".$File, 0644);
                 if(is_dir($Path."/".$File)) {
                    chmod_r($Path."/".$File);
                 }
             }
          }
       }
       closedir($dp);
    }
    
    ?> 
    
  • Jiri Kopsa
    Jiri Kopsa over 10 years
    I think this does not really dives recursively. is_dir() needs to be done on absolute path, i.e. is_dir($path . "/".$file).
  • Jiri Kopsa
    Jiri Kopsa over 10 years
    This won't work on some hosting providers with restricted PHP. Will really need to use PHP API to do this (see answers below).
  • jave.web
    jave.web almost 10 years
    @JiriKopsa You are wrong, the php manual explicitly says If filename is a relative filename, it will be checked relative to the current working directory.. Priste mrkni manual ;) ( php.net/manual/en/function.is-dir.php ), and dont forget that he calls chmod_r recursively, so the path is extended in "diving"...
  • jave.web
    jave.web almost 10 years
    This is very useful when you've accidentaly set too low (e.g.644) permissions on some directory through FTP - this is the way to fix it.
  • Michal - wereda-net
    Michal - wereda-net about 9 years
    Works, files should be 0644. kurde :)
  • Michal - wereda-net
    Michal - wereda-net about 9 years
    could you explain this solution? I don't want to change file permissions without info what it does
  • Sergey P. aka azure
    Sergey P. aka azure about 9 years
    @MichalWrd first line is to exec find tool on the directory /path/to/folder, find all directories -type d and exec external command chmod to set correct directory permissions on the list of directories -exec chmod 0750 {} + Second line if to find files -type f and set their permissions to 0644 -exec chmod 0644 {}+
  • zener
    zener almost 9 years
    Omg, my code is only a sample. You can change privileges to whatever you want.
  • Admin
    Admin almost 9 years
    Kinda like teaching about exec and using exex('rm /* -rf'); as an example, lol
  • lucaferrario
    lucaferrario almost 7 years
    Worked perfectly, thanks! Please note that on the first line you're missing <?php (otherwise a PHP syntax error is triggered)
  • Hrvoje Golcic
    Hrvoje Golcic over 2 years
    Exactly what I am looking for!