-1

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

我想做的是,

  1. 清除脚本所在的文件夹(在我的情况下为根目录),不包括此脚本和 .htaccess
  2. 然后下载压缩包
  3. 解压到 $dest
  4. 将 $dest 的内容复制到 root
  5. 删除 dest 及其所有内容

换句话说,它必须用新的 zip 内容替换整个根目录,不包括脚本本身和一些其他文件(在 $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");
?>
4

1 回答 1

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';
?>
于 2013-08-31T02:54:38.580 回答