您的位置:首页 > 编程语言 > PHP开发

php利用内置的svn函数实现的svn版本号的提交、更新、删除、恢复等功能

2013-08-21 17:40 926 查看
svnPeer.class.php

<?php
/**
* php操作svn类,全部利用php内置的svn函数
*
* @author wengxianhu
* @date 2013-08-05
*/
class svnPeer
{
/* svn用户名 */
public $svn_user = '';
/* svn密码 */
public $svn_password = '';
/* 来源路径 */
public $source_path = '';
/* 目标路径 */
public $dest_path = '';
/* 备份包的路径 */
public $package_path = '';

/**
* 构造函数
*
* @author wengxianhu
* @date 2013-08-05
* @param string $svn_user
* @param string $svn_password
* @param string $source_path
* @param string $dest_path
* @return void
*/
public function __construct ($configs = array())
{
if (empty($configs))
{
die('missing parameter');
}
$this->svn_user = $configs['svn_user'];
$this->svn_password = $configs['svn_password'];
$this->source_path = $configs['source_path'];
$this->dest_path = $configs['dest_path'];
$this->package_path = $configs['package_path'];
$this->_svn_connect();
}

/**
* 配置SVN使用默认的用户名和密码
*
* @author wengxianhu
* @date 2013-08-05
* @return void
*/
public function _svn_connect ()
{
svn_auth_set_parameter(SVN_AUTH_PARAM_DEFAULT_USERNAME, $this->svn_user);
svn_auth_set_parameter(SVN_AUTH_PARAM_DEFAULT_PASSWORD, $this->svn_password);
}

/**
* 返回svn版本中的一个文件的内容,默认返回最新的版本号内容
*
* @author wengxianhu
* @date 2013-08-05
* @param string $repos_url
* @param int $revision_no 版本号
* @return string
*/

/*
public function _svn_cat ($repos_url, $revision_no = 0)
{
$url = $this->svn_path . '!svn/bc/' . $revision_no . $repos_url;
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPGET, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ;
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$this->svn_user:$this->svn_password");
curl_setopt($ch, CURLOPT_HEADER, 0);

$result=curl_exec($ch);
curl_close($ch);
return $result;
}
*/

/**
* 将新增、修改的文件提交到svn中
*
* @author wengxianhu
* @date 2013-08-05
* @param string $msg 版本说明
* @param array $dir_array 目录的绝对路径(目录要一级级往下,不可乱了顺序,如:a、a/a1、b、b/b1、b/b2)
* @param array $file_array 文件的绝对路径
* @param string $package_name 备份包的目录名
* @return array 返回版本号、日期、作者
*/
public function _svn_commit ($msg = '', $dir_array = array(), $file_array = array(), $package_name = '')
{
$info = '';
$commit_array = array(); // 将要提交到svn的新目录、新文件、更新文件的路径集合
if (0 < svn_update($this->dest_path)) // 先更新svn
{
if (svn_cleanup($this->dest_path)) // 清理svn
{
$error_array = array();

/* 将新目录加入版本库中 */
$dest_dir = '';

foreach ($dir_array as $dir_k=>$dir_v)
{
$dest_dir = $this->dest_path . $dir_v; // 目标目录路径
if (false === @svn_ls($dest_dir))
{
$this->_mkdirm($dest_dir);
if (false != @svn_add($dest_dir, false))
{
array_push($commit_array, $dest_dir);
}
else
{
array_push($error_array, $dest_dir);
break;
}
}
}

$dest_files = '';
$source_files = '';
$copy_file_array = array(); //覆盖成功的文件集合
foreach ($file_array as $file_k=>$file_v)
{
$dest_files = $this->dest_path . $file_v; // 目标文件路径
/* 拷贝文件 */
$source_files = $this->source_path . $package_name . '/' . $file_v; // 源文件路径
if (false != $this->_copy_file($source_files, $dest_files))
{
array_push($copy_file_array, $dest_files); //用以提交失败后的还原
if (false === @svn_ls($dest_files))
{/* 将新文件加入版本库中 */
if (false != @svn_add($dest_files, false))
{
array_push($commit_array, $dest_files);
}
else
{
array_push($error_array, $dest_files);
break;
}
}
else
{
array_push($commit_array, $dest_files);
}
}
else
{
array_push($error_array, $dest_files);
break;
}
}
$commit_array = array_unique($commit_array);

/* 将新增、修改的文件和目录提交到svn中 */
$commit_status = false;
if (empty($error_array))
{
$info = @svn_commit($msg, $commit_array);
if (false == $info)
{
$commit_status = true;
$info = '提交svn失败';
}
elseif ($info[0] == -1)
{
$info = '文件包里的文件没做任何修改,不能提交';
}
}

/* 提交失败后要把覆盖过去的文件给删除还原 */
if (!empty($error_array) || $commit_status == true)
{
if (!empty($copy_file_array))
{
$er_num = 0;
foreach ($copy_file_array as $er_k=>$er_v)
{
if (false == @unlink($er_v))
{
$er_num++;
break;
}
}
if ($er_num == 0)
{
if (false == @svn_update($this->dest_path))
{
$info = '提交svn失败,删除涉及文件后更新失败,请手工更新';
}
}
else
{
$info = '提交svn失败,涉及的文件部分删除失败,请手工删除后更新';
}
}
}
}
}
return $info;
}

/**
* 删除svn版本库中的文件
*
* @author wengxianhu
* @date 2013-08-05
* @param string $msg 版本说明
* @param array $file_array 元素值是绝对路径的文件
* @return array
*/
public function _svn_delete ($msg = '', $file_array = array())
{
$info = '';
$delete_array = array();
$error_array = array();

/* 将删除的文件移除版本库 */
$dest_files = '';
if (svn_cleanup($this->dest_path))
{
foreach ($file_array as $_k=>$_v)
{
$dest_files = $this->dest_path . $_v;
array_push($delete_array, $dest_files);
if (false === @svn_delete($dest_files))
{
array_pop($delete_array);
}
else
{
array_push($error_array, $dest_files);
break;
}
}

/* 将删除的文件提交到svn中 */
if (empty($error_array))
{
$info = @svn_commit($msg, $delete_array);
}
}
return $info;
}

/**
* 提交svn前生成版本号中各个文件最新的文件,当做备份包
*
* @author wengxianhu
* @date 2013-08-05
* @param array $file_array 文件路径名
* @param string $package_name 备份包名
* @return boolean 成功为true,失败为false
*/
public function _svn_bak_package ($file_array = array(), $package_name = '')
{
//生成备份包的目录名称为'trunk版本号'
if (!empty($file_array) && !empty($package_name))
{
$files = '';
$source_files = '';
$dest_files = '';
$error_array = array();
foreach ($file_array as $_k=>$_v)
{
$files = preg_replace('/^[^\/]+\/(.*)$/', '$1', $_v);
if (file_exists($this->dest_path . $files))
{
$source_files = $this->dest_path . $files;
$dest_files = $this->package_path . $package_name . '/' . $files;
$revision_no = $this->_get_new_revision_no($source_files); //获取文件最新的版本号
if (!empty($revision_no))
{
$this->_mkdirm(dirname($dest_files));
$lbv_export = svn_export($source_files, $dest_files, false, $revision_no);
if (false == $lbv_export)
{
array_push($error_array, $files);
break;
}
}
}
}
if (empty($error_array))
{
return true;
}
}
return false;
}

/**
* 恢复指定的svn版本库中的文件
*
* @author wengxianhu
* @date 2013-08-05
* @param string $src 源
* @param string $dst 版本号
* @return array
*/
public function _recurse_copy($src, $dst)
{
$dir = opendir($src);
@mkdir($dst);
while(false !== ( $file = readdir($dir)) )
{
if (( $file != '.' ) && ( $file != '..' ))
{
if ( is_dir($src . $file) ) {
$this->_recurse_copy($src . $file,$dst . $file);
}
else
{
if (false != copy($src . $file,$dst . $file))
{
return false;
}
}
}
}
closedir($dir);
return true;
}

/**
* 恢复指定的svn版本库中的文件
*
* @author wengxianhu
* @date 2013-08-05
* @param int $revision_no 版本号
* @param string $package_name 备份包名
* @return array
*/
public function _svn_revert ($revision_no = '', $package_name = '')
{
$info = '';
if (0 < svn_update($this->dest_path))
{
$log_array = @svn_log($this->dest_path, $revision_no); // 获取指定版本号的相关文件和目录的路径
if (is_array($log_array) && !empty($log_array))
{
$log_array = current($log_array);
$msg = "还原{$revision_no}版本号," . $log_array['msg'];
$files = $log_array['paths'];
$error_array = array();
$commit_array = array();

foreach ($files as $_k=>$_v)
{
$source_files = '';
$dest_files = '';
$dest_files = $this->dest_path . preg_replace('/^\/(.*)/', '$1', $_v['path']);
/* 只针对文件恢复,不管目录 */
if (file_exists($dest_files))
{
/* 恢复版本号的核心 */
if ('A' == $_v['action'])
{/* 删除新增加的文件 */
if (true == svn_delete($dest_files))
{
array_push($commit_array, $dest_files);
}
else
{
array_push($error_array, $dest_files);
break;
}
}
else /* 恢复被删除、被更改的文件 */
{
$source_files_cp = $this->package_path . $package_name . $_v['path'];
$dest_files_cp = $dest_files;
if (false == $this->_copy_file($source_files_cp, $dest_files_cp))
{
array_push($error_array, $dest_files_cp);
break;
}
array_push($commit_array, $dest_files_cp);
}
}
}

/* 将修改、删除的文件和目录提交到svn中 */
$commit_status = false;
if (empty($error_array))
{
$info = @svn_commit($msg, $commit_array);
if (false == $info)
{
$commit_status = true;
$info = '还原时提交svn失败';
}
elseif ($info[0] == -1)
{
$info = '文件包里的文件没做任何修改,不能提交';
}
}

/* 提交失败后要把覆盖过去的文件给删除还原 */
if (!empty($error_array) || $commit_status == true)
{
$er_num = 0; //删除失败次数
foreach ($error_array as $er_k=>$er_v)
{
if (false == @unlink($er_v))
{
$er_num++;
break;
}
}
if ($er_num == 0)
{
if (false == @svn_update($this->dest_path))
{
$info = '提交svn失败,删除涉及文件后更新失败,请手工更新';
}
else
{
$info = '还原失败,个别文件svn删除或覆盖出错';
}
}
else
{
$info = '提交svn失败,涉及的文件部分删除失败,请手工删除后更新';
}
}
}
else
{
$info = '该版本号不存在'; //不存在该版本号
}
}
return $info;
}

/**
* 获取版本号的说明
*
* @author wengxianhu
* @date 2013-08-05
* @param string $files svn文件,绝对路径
* @param int $revision_no svn版本号
* @return string 版本号说明
*/
public function _svn_get_msg ($files = '', $revision_no = '')
{
$log_last_info = current(svn_log($files, $revision_no, $revision_no, 1));
$msg = $log_last_info['msg'];
return $msg;
}

/**
* 获取文件最新的版本号
*
* @author wengxianhu
* @date 2013-08-05
* @param string $files svn文件,绝对路径
* @return int 版本号
*/
public function _get_new_revision_no ($files = '')
{
$ls_last_info = svn_ls($files);
if (false == $ls_last_info)
{
return '';
}
$ls_last_info = current($ls_last_info);
$revision_no = $ls_last_info['created_rev'];
return $revision_no;
}

/**
* 拷贝文件
*
* @author wengxianhu
* @date 2013-08-05
* @param string $source_files 源文件
* @param string $dest_files 目标文件
* @return bool
*/
public function _copy_file ($source_files, $dest_files)
{
if (copy($source_files, $dest_files))
{
return chmod($dest_files, 0644); //文件权限
}
return false;
}

/**
* 创建文件夹
*
* @author wengxianhu
* @date 2013-08-05
* string $path 文件路径(不包括文件名)
* return void
*/
public function _mkdirm ($path)
{
if (!file_exists($path))
{
$this->_mkdirm(dirname($path));
mkdir($path, 0755);
}
}

/**
* 获取一个时间段内的svn的版本号信息
*
* @author wengxianhu
* @date 2013-08-15
* @param array $array 数组参数
* @return boolean
*/
public function _get_svn_list($array = array())
{
$start_revision = $array['start_revision'];
$end_revision = $array['end_revision'];
if (empty($start_revision)) $start_revision = 0; //起初默认为0
/* 结束默认为最新版本号 */
if (empty($end_revision))
{
$end_revision = svn_update($this->dest_path);
if (false == $end_revision)
{
return false;
}
}
/* 结束版本号大于起初版本号,说明有版本需要同步 */
if ($end_revision > $start_revision)
{
$start_revision = $start_revision + 1;
$svn_list = svn_log($this->dest_path, $start_revision, $end_revision);
if ($svn_list)
{
return $svn_list;
}
}
return false;
}
}

zip.class.php
<?php
/**
* Zip 文件包工具
*
* @author wengxianhu
* @date 2013-08-05
*/

class ZipFolder
{
protected $zip;
protected $root;
protected $ignored_names;

public function __construct(){
$this->zip = new ZipArchive;
}

/**
* 解压zip文件到指定文件夹
*
* @access public
* @param string $zipfile 压缩文件路径
* @param string $path 压缩包解压到的目标路径
* @return booleam 解压成功返回 true 否则返回 false
*/
public function unzip ($zipfile, $path) {
if ($this->zip->open($zipfile) === true) {
$file_tmp = @fopen($zipfile, "rb");
$bin = fread($file_tmp, 15); //只读15字节 各个不同文件类型,头信息不一样。
fclose($file_tmp);
/* 只针对zip的压缩包进行处理 */
if (true === $this->getTypeList($bin))
{
$result = $this->zip->extractTo($path);
$this->zip->close();
return $result;
}
else
{
return false;
}
}
return false;
}

/**
* 创建压缩文件
*
* @access public
* @param string $zipfile 将要生成的压缩文件路径
* @param strng $folder 将要被压缩的文件夹路径
* @param array $ignored 要忽略的文件列表
* @return booleam 压缩包生成成功返回true 否则返回 false
*/
public function zip ($zipfile, $folder, $ignored = null) {
$this->ignored_names = is_array($ignored) ? $ignored : $ignored ? array($ignored) : array();
if ($this->zip->open($zipfile, ZIPARCHIVE::CREATE) !== true) {
throw new Exception("cannot open <$zipfile>\n");
}
$folder = substr($folder, -1) == '/' ? substr($folder, 0, strlen($folder)-1) : $folder;
if(strstr($folder, '/')) {
$this->root = substr($folder, 0, strrpos($folder, '/')+1);
$folder = substr($folder, strrpos($folder, '/')+1);
}
$this->createZip($folder);
return $this->zip->close();
}

/**
* 递归添加文件到压缩包
*
* @access private
* @param string $folder 添加到压缩包的文件夹路径
* @param string $parent 添加到压缩包的文件夹上级路径
* @return void
*/
private function createZip ($folder, $parent=null) {
$full_path = $this->root . $parent . $folder;
$zip_path = $parent . $folder;
$this->zip->addEmptyDir($zip_path);

$dir = new DirectoryIterator($full_path);

foreach($dir as $file) {
if(!$file->isDot()) {
$filename = $file->getFilename();

if(!in_array($filename, $this->ignored_names)) {
if($file->isDir()) {
$this->createZip($filename, $zip_path.'/');
}else {
$this->zip->addFile($full_path.'/'.$filename, $zip_path.'/'.$filename);
}
}
}
}
}

/**
* 读取压缩包文件与目录列表
*
* @access public
* @param string $zipfile 压缩包文件
* @return array 文件与目录列表
*/
public function fileList($zipfile) {
$file_dir_list = array();
$file_list = array();

if ($this->zip->open($zipfile) == true) {
for ($i = 0; $i < $this->zip->numFiles; $i++) {
$numfiles = $this->zip->getNameIndex($i);
if (preg_match('/\/$/i', $numfiles))
{
$file_dir_list[] = $numfiles;
}
else
{
$file_list[] = $numfiles;
}
}
}

return array('files'=>$file_list, 'dirs'=>$file_dir_list);
}

/**
* 得到文件头与文件类型映射表
*
* @author wengxianhu
* @date 2013-08-10
* @param $bin string 文件的二进制前一段字符
* @return boolean
*/
private function getTypeList ($bin)
{
$array = array(
array("504B0304", "zip")
);

foreach ($array as $v)
{
$blen = strlen(pack("H*", $v[0])); //得到文件头标记字节数
$tbin = substr($bin, 0, intval($blen)); ///需要比较文件头长度
if(strtolower($v[0]) == strtolower(array_shift(unpack("H*", $tbin))))
{
return true;
}
}
return false;
}
}

filedir.class.php
<?php
/**
* 文件类
*
* @author wengxianhu
* @date 2013-08-14
*/
class filedir
{
/* 文件数组 */
public $file_array = array();
/* 目录数组*/
public $folder_array = array();
/* 全部数组 */
public $all_array = array();

/**
* 读取目录下的文件及子目录的路径
*
* @author wengxianhu
* @date 2013-08-05
* @param string $path 文件路径(不包括文件名)
* @param string $file_array 文件数组
* @param string $folder_array 目录数组
* @param string $all_array 全部数组
* return array
*/
public function searchFile($path, $file_array, $folder_array, $all_array)
{
if(is_dir($path))
{ //检查文件目录是否存在
$H = @ opendir($path);
while(false !== ($_file=readdir($H)))
{
//检索目录
if(is_dir($path."/".$_file) && !in_array($_file, array(".", "..", "Thumbs.db")))
{
array_push($this->folder_array, $path."/".$_file);
array_push($this->all_array, $path."/".$_file);
$this->searchFile($path."/".$_file, $this->file_array, $this->folder_array, $this->all_array);
//检索文件
}
elseif(file_exists($path."/".$_file) && !in_array($_file, array(".", "..", "Thumbs.db")))
{
array_push($this->file_array,$path."/".$_file);
array_push($this->all_array, $path."/".$_file);
}
}
closedir($H);
}
elseif(file_exists($path))
{
array_push($this->file_array, $path);
array_push($this->all_array, $path);
}

return array('dirs'=>$this->folder_array, 'files'=>$this->file_array, 'all'=>$this->all_array);
}

/**
* 循环删除目录和文件函数
*
* @author wengxianhu
* @date 2013-08-15
* @param string $dirName 目录路径
* return array
*/
public function delDirAndFile($dirName)
{
if ( $handle = opendir( "$dirName" ) )
{
while ( false !== ( $item = readdir( $handle ) ) )
{
if ( $item != "." && $item != ".." )
{
if ( is_dir( "$dirName/$item" ) )
{
$this->delDirAndFile( "$dirName/$item" );
}
else
{
unlink( "$dirName/$item" );
}
}
}
closedir( $handle );
rmdir( $dirName );
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐