Php 递归删除文件夹时排除文件

Php 递归删除文件夹时排除文件,php,recursion,bitbucket,rmdir,Php,Recursion,Bitbucket,Rmdir,我正在从事公共项目,它完全用GIT代替了基于PHP项目的FTP部署方法。在网站的根目录中放置1个file-deployPHP。这就是全部。当您将某些内容推送到Bitbucket git repo中时,此脚本将获取zip并用zip内容替换所有网站文件 我想做的是 清除脚本所在的文件夹(在我的示例中为root),不包括此脚本和.htaccess 然后下载zip 解压缩到$dest 将$dest的内容复制到根目录中 删除dest及其所有内容 换句话说,它必须用新zip的内容替换整个根目录,不包括脚本本

我正在从事公共项目,它完全用GIT代替了基于PHP项目的FTP部署方法。在网站的根目录中放置1个file-deployPHP。这就是全部。当您将某些内容推送到Bitbucket git repo中时,此脚本将获取zip并用zip内容替换所有网站文件

我想做的是

  • 清除脚本所在的文件夹(在我的示例中为root),不包括此脚本和.htaccess
  • 然后下载zip
  • 解压缩到$dest
  • 将$dest的内容复制到根目录中
  • 删除dest及其所有内容
  • 换句话说,它必须用新zip的内容替换整个根目录,不包括脚本本身和少数其他文件(列在$exc数组中)。这就是全部。问题是,我的函数递归地
    rmdir\u
    不排除文件,而是删除包括脚本在内的所有文件。我错过了什么

    对于脚本,您还可以建议哪些其他优化

    Thx提前

    <?php
    
    // Set these dependant on your BB credentials    
    $username = '';
    $password = '';
    
    // your Bitbucket repo name
    $reponame = "";
    
    // extract to
    $dest = "./"; // leave ./ for relative destination
    
    
    //Exclusion list
    $exc = array("deploy.php", ".htaccess");
    
    // Grab the data from BB's POST service and decode
    $json = stripslashes($_POST['payload']);
    $data = json_decode($json);
    
    // set higher script timeout (for large repo's or slow servers)
    set_time_limit(5000);
    
    // Set some parameters to fetch the correct files
    $uri = $data->repository->absolute_url;
    $node = $data->commits[0]->node;
    $files = $data->commits[0]->files;
    
    //Clear Root 
    rmdir_recursively(".");
    
    // download the repo zip file
    $fp = fopen("tip.zip", 'w');
    
    $ch = curl_init("https://bitbucket.org/$username/$reponame/get/$node.zip");
    curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_FILE, $fp);
    
    $data = curl_exec($ch);
    
    curl_close($ch);
    fclose($fp);
    
    // unzip
    $zip = new ZipArchive;
    $res = $zip->open('tip.zip');
    if ($res === TRUE) {
        $zip->extractTo('./');
        $zip->close();
    } else {
        die('ZIP not supported on this server!');
    }
    
    // function to delete all files in a directory recursively
    function rmdir_recursively($dir) {
        global $exc;
        if(in_array($dir,$exc)) return false;
        if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
            foreach (scandir($dir) as $file) { 
                if ($file == '.' || $file == '..') continue; 
                if (!rmdir_recursively($dir . DIRECTORY_SEPARATOR . $file)) { 
                    chmod($dir . DIRECTORY_SEPARATOR . $file, 0777); 
                    if (!rmdir_recursively($dir . DIRECTORY_SEPARATOR . $file)) return false; 
                }; 
            } 
            return rmdir($dir); 
    }
    
    // function to recursively copy the files
    function copy_recursively($src, $dest) {
        if (is_dir($src)) {
            if ($dest != "./")
                rmdir_recursively($dest);
            @mkdir($dest);
            $files = scandir($src);
            foreach ($files as $file)
                if ($file != "." && $file != "..")
                    copy_recursively("$src/$file", "$dest/$file");
        }
        else if (file_exists($src))
            copy($src, $dest);
        rmdir_recursively($src);
    }
    
    // start copying the files from extracted repo and delete the old directory recursively
    copy_recursively("$username-$reponame-$node", $dest);
    
    // delete the repo zip file
    unlink("tip.zip");
    ?>
    
    试试这个

    <?php
    
    // set higher script timeout (for large repo's or slow servers)
    $timeLimit = 5000;
    
    ///////////////////////////////////////////////////////////////////////////////////////
    $mode = intval(isset($_POST['payload']));
    
    if (isset($_GET['commit']))
        $mode = 2;
    
    $force = isset($_GET['force']);
    $owner = (isset($owner)) ? $owner : $username; // if user is owner
    $repo = $reponame;
    $response = "";
    
    if ($mode == 0) { // manual deploy
    
        function callback($url, $chunk) {
            global $response;
            $response .= $chunk;
            return strlen($chunk);
        }
    
        ;
    
        $ch = curl_init("https://api.bitbucket.org/1.0/repositories/$owner/$repo/changesets?limit=1");
    
        curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
    
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent:Mozilla/5.0'));
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'callback');
        curl_exec($ch);
        curl_close($ch);
    
        $changesets = json_decode($response, true);
        $node = $changesets['changesets'][0]['node'];
        $raw_node = $changesets['changesets'][0]['raw_node'];
    } else if ($mode == 1) { // auto deploy
        $json = stripslashes($_POST['payload']);
        $data = json_decode($json);
        // Set some parameters to fetch the correct files
        $uri = $data->repository->absolute_url;
        $node = $data->commits[0]->node;
        echo $node;
        $files = $data->commits[0]->files;
    } else if ($mode == 2) { // deploy with hash code
        $node = $_GET['commit'];
        $node = substr($node, 0, 12);
        echo 'commit: ' . $node . "\n";
    }
    // Check last commit hash
    
    if (isset($_GET['updated'])) {
        echo "\n<br>Bitbucket Deploy Updated<br>\n";
    }
    
    set_time_limit($timeLimit);
    
    // Grab the data from BB's POST service and decode
    // Clear Root
    // download the repo zip file
    
    if (!$force && file_exists('lastcommit.hash')) {
        $lastcommit = file_get_contents('lastcommit.hash');
        if ($lastcommit == $node)
            die('Project is already up to date');
    }
    
    file_put_contents('lastcommit.hash', $node);
    
    
    $fp = fopen("tip.zip", 'w');
    
    $ch = curl_init("https://bitbucket.org/$owner/$reponame/get/$node.zip");
    curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_FILE, $fp);
    
    $data = curl_exec($ch);
    
    curl_close($ch);
    fclose($fp);
    
    $exc["files"][] = realpath("tip.zip");
    
    $tipsize = filesize("tip.zip");
    
    if ($tipsize < 50) {
        die("Commit not found");
    }
    
    if ($autoUpdate)
        updateDeploy();
    
    //var_dump($exc);
    //die();
    
    
    RemoveDir(realpath($dest), true, $exc);
    
    
    // unzip
    $zip = new ZipArchive;
    $res = $zip->open('tip.zip');
    if ($res !== TRUE) {
        die('ZIP not supported on this server!');
    }
    
    $zip->extractTo("$dest/");
    $zip->close();
    
    copy_recursively("$owner-$reponame-$node", $dest);
    
    RemoveDir(realpath("$owner-$reponame-$node"), false);
    @rmdir("$owner-$reponame-$node");
    // Delete the repo zip file
    unlink("tip.zip");
    
    // function to delete all files in a directory recursively
    
    function updateDeploy() {
        global $force;
        global $dest;
        global $mode;
        $updated = isset($_GET['updated']);
        //var_dump($_GET);
        if ($updated)
            return true;
    
        $response = "";
    
        $response = file_get_contents("https://api.bitbucket.org/1.0/repositories/codearts/bitbucket-deploy/changesets?limit=1");
    
        $changesets = json_decode($response, true);
        $node = $changesets['changesets'][0]['node'];
        $raw_node = $changesets['changesets'][0]['raw_node'];
    
        $lastcommit = file_get_contents('data.hash');
        if (file_exists('data.hash')) {    //   if (!$force && file_exists('data.hash')) {
            $lastcommit = file_get_contents('data.hash');
            if ($lastcommit == $node)
                return;
        }
        file_put_contents('data.hash', $node);
        $deployLink = "https://bitbucket.org/codearts/bitbucket-deploy/get/$node.zip";
        $deploy = file_get_contents($deployLink);
    
        $f = fopen("deploy.zip", "w");
        fwrite($f, $deploy);
        fclose($f);
        $zip = new ZipArchive;
        $res = $zip->open('deploy.zip');
        if ($res !== TRUE) {
            die('ZIP not supported on this server!');
        }
        $zip->extractTo("$dest/");
        $zip->close();
        unlink('deploy.php');
        copy("codearts-bitbucket-deploy-$node/deploy.php", 'deploy.php');
        //unlink("codearts-bitbucket-deploy-$node/deploy.php");
        RemoveDir(realpath("codearts-bitbucket-deploy-$node"), false);
        @rmdir(realpath("codearts-bitbucket-deploy-$node"));
    
        $url = "http://" . $_SERVER['HTTP_HOST'] . "/deploy.php?updated" . (($force) ? '&force' : '');
    
        header("Location:" . $url);
        die();
    
    //    if($mode != 1) echo "\n<br>Bitbucket Deploy Updated<br>\n";
    }
    
    // Deleting with exclude list
    
    
    function checkExcluding($path, $excludinglist) {
        if (!isset($excludinglist["files"]))
            return false;
        if (!is_dir($path)) {
            return in_array($path, $excludinglist["files"]);
        }
        else
            return in_array($path, $excludinglist["dirs"]);
    }
    
    function RemoveDir($dir, $exclude = false, $excludelist = array()) {
        $it = new RecursiveDirectoryIterator($dir);
        $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
        //  var_dump($files);
        foreach ($files as $file) {
            if ($exclude && checkExcluding($file->getRealPath(), $excludelist)) {
                //  echo 'Excluding: ' . $file->getRealPath() . '<br>';
                continue;
            }
    
            if ($file->isDir()) {
                @rmdir($file->getRealPath());
                //echo 'DIR: ' . $file->getRealPath() . '<br>';
            } else {
                @unlink($file->getRealPath());
                //echo 'FILE: ' . $file->getRealPath() . '<br>';
            }
        }
        if (file_exists($dir))
            @rmdir($dir);
    }
    
    function copy_recursively($src, $dest) {
        //var_dump($src);
        global $exc;
        $excludeDirsNames = array();
        $excludeFileNames = $exc["files"];
        //     var_dump(  $excludeFileNames  );
    
        if (is_dir('' . $src)) {
            //  var_dump($src);
            // if ($dest != "./")
            //   rmdir_recursively($dest);
            @mkdir($dest);
            $files = scandir($src);
    
    
    
            // var_dump( $excludeFileNames );
    
            foreach ($files as $file) {
                if (!in_array($file, $excludeDirsNames)) {
    
                    if ($file != "." && $file != "..")
                        copy_recursively("$src/$file", "$dest/$file");
                }
            }
        }
        else if (file_exists($src)) {
    
            $filename = $src;
            $filename = end(explode("/", $src));
            //$filename = $filename[count( $filename)-2];
            if (!in_array($filename, $excludeFileNames)) {
                //var_dump($filename);
                // var_dump(in_array( $filename, $excludeDirsNames));
                copy($src, $dest);
            }
        }
        //  rmdir_recursively($src);
    }
    
    if ($mode != 1)
        echo '<br>Done';
    ?>
    
    
    
    “您可以为脚本提供哪些其他优化建议?”-将文件系统抽象与
    DirectoryIterator一起使用,它是递归的。提供一个
    FilterIterator
    来排除你的文件。@hakre你能应用你对代码的建议吗?@hakre这是一个公共项目,我试图让git和php爱好者的生活更轻松,这就是为什么你不仅帮助我,而且还帮助社区请使用搜索。我已经在现场给出了一些示例(和其他示例一样),这些示例也应该有场外示例。还可以查看现有项目,例如有
    Symfony\Component\Finder\Finder
    。此外,由于您已经解包到´$dest`中,您可以使用该目录复制其中的永久文件,然后将整个文件移动到其最终目的地(或更改符号链接)。