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

时间:2012-10-07 08:51:36

标签: php recursion bitbucket rmdir

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

我想做的是,

  1. 清除脚本所在的文件夹(在我的情况下为root),排除此脚本和.htaccess
  2. 然后下载zip
  3. 解压缩到$ dest
  4. 将$ dest的内容复制到root
  5. 删除dest及其所有内容
  6. 换句话说,它必须用新的zip内容替换整个root,不包括脚本本身和少量其他文件(在$ exc数组中列出)。就这样。问题是,我的函数rmdir_recursively不排除文件,删除所有包括脚本。我错过了什么?

    您可以为脚本提出哪些其他优化建议?

    提前谢谢。

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

1 个答案:

答案 0 :(得分:0)

试试这个

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