使用PHP操作SVN基础类
本帖最后由 cu_Cbear 于 2012-01-23 02:35 编辑使用PHP操作SVN基础类
我不想使用PECL包中php svn扩展,一方面对PHP版本有要求,另外一方面对svn代码包有限制,不过最严重的是:对服务器PHP环境的依赖。
一个基础的svn类,应该实现基本的svn操作,如:checkout、update、commit、copy(最常用到)
【目的】
作为一个码农,写出一个被众人使用的组件、类库总是一件令人兴奋的事情,另外,代码的重用性也提倡将某一个方面的操作使用代码封装。
在自动化软件管理中,将代码从svn获取到当前地点,然后再对代码进行部署,并且通过可视化界面对此流程进行管理,这是个不错的想法。另外,通过对svn的管理,实现对代码版本的管理也是一件很有意义的事情。定期去检查代码,然后通知管理员改动信息,都是很好的想法。
【流程】
我想过从svn的协议部分下手,太过复杂,想我几天内是没有办法把它弄完的。因此,通过PHP的shell_exec()下手是个不错的选择。
view plaincopyprint?$result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);
$result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);通过php执行shell,可以有各种空间来进行扩展和使用,但是有如下几点需要注意:
【环境依赖】
依赖Linux环境,
对操作目录、临时目录有操作权限
如果是web环境,同时需要保证apache的执行者具有权限。
【错误处理】
在调用SHELL的时候,倘若svn出错(这是不可避免的),错误不会通过标准输出(STDOUT)输出,而是通过标准错误(STDERR)来输出,标准错误不会被PHP捕捉到,但是会被apache或者操作系统捕捉到,造成PHP执行失败和无法显示的问题。
在这里,我选择了利用shell将错误信息重定向到一个临时文件,然后去读取临时文件来判断执行时是否有错误发生。 view plaincopyprint? private function shell($cmd){
$opts = '';
foreach($this->opts as $key => $item){
if(!emptyempty($item)){
$opts .= "--{$key} {$item} ";
}
}
$result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);
if($this->isResultError()){
return false;
}
return $result;
}
private function shell($cmd){
$opts = '';
foreach($this->opts as $key => $item){
if(!empty($item)){
$opts .= "--{$key} {$item} ";
}
}
$result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);
if($this->isResultError()){
return false;
}
return $result;
}【选项】
选项包括:svn的用户名和密码,或者存储svn基本数据的目录(当然前提是有权限读取),可以通过设置来进行 view plaincopyprint? public function setOptions($options = array()){
$this->opts = array_merge($this->opts, $options);
}
public function setOptions($options = array()){
$this->opts = array_merge($this->opts, $options);
}【最终】
通过执行测试 和 phpdoc生成文档,即可完成一个基础类的创建
【开闭原则】
也许你知道,也许也不知道,说实话,我对它的理解仅仅局限于字面上。
使每一个与你共事的同事了解开闭原则是一件很重要的事,它能帮助你编写更多可重用的代码类库。
开(对扩展开放)闭(对修改关闭)保证了代码的可重用性和可维护性。
最后,将整个类库贴上。
view plaincopyprint?<?php
/**
* For svn use by php
*
* This class allow you checkout svn files through web
* And allow you update files
* I hope in the later version, it can handle commit and other actions
*
* @example
* <code>
* $phpsvn = new phpsvn();
* $phpsvn->setOptions(array(
*'username' => 'yourname',
*'password' => 'yourpassword'
* ));
* $phpsvn->setPath($svnpath, $localpath);
* $r = $phpsvn->checkout();
* if($r === false){
*echo $phpsvn->error();
* }else{
*print_r($r);
* }
* </code>
* @author hufeng<hufeng@staff.sina.com.cn>
* @version v1.0
* @access sflib
* @package sflib
* @category phpsvn
* @copyright 2012-2013@copyright sflib
*/
class phpsvn
{
/**
* svn command options
*
* @var array
*/
private $opts = array(
'username' => '',
'password' => '',
'config-dir' => '',///usr/home/finance/.subversion
);
/**
* error log file
*
* Will not save data in this file
* Just a tmp file store tmp error message
* @var string
*/
private $errorfile = '/tmp/phpsvn.err';
/**
* Error message
*
* If no error, error = ''
* @var string
*/
private $error = '';
/**
* The value to return
*
* @var array
*/
private $retValue = array();
/**
* Svn path
*
* @var string
*/
private $svnpath = '';
/**
* Local file path where file stored
*
* @var string
*/
private $targetPath = '.';
/**
* actions tags
*
* @var array
*/
private $shortTags = array('a', 'u', 'd');
/**
* Set opts of svn command
*
* allow opts:
* username : your svn username
* password : your svn password
* config-dir : your execute user config dir
* @param array $options
*/
public function setOptions($options = array()){
$this->opts = array_merge($this->opts, $options);
}
/**
* Set svn path & localpath
*
* @param string $svnpath svn path
* @param string $targetpath local path
* @return void
*/
public function setPath($svnpath, $targetpath = '.'){
$this->svnpath = $svnpath;
$this->targetPath = realpath($targetpath);
}
/**
* update from server
*
* @return mixed array on success or false on error
*/
public function update(){
return $this->doCmd('up');
}
/**
* commit file to server
*
* @return mixed array on success or false on error
*/
public function commit(){
return $this->doCmd('ci');
}
/**
* Add file to svn
*
* @param string $file filename
* @return mixed array on success or false on error
*/
public function add($file){
return $this->doCmd('add', $file);
}
/**
* Chectout file from svn to local
*
* @return mixed array on success or false on error
*/
public function checkout(){
return $this->doCmd('co', $this->svnpath);
//Checked out revision 240772
}
/**
* Execute command for svn
*
* support commands:add/checkout(co)/cleanup/commit(ci)/copy(cp)/delete(del,remove,rm)/diff(di)/update (up)
* todo commands:export
* help (?, h)
* import
* info
* list (ls)
* lock
* log
* merge
* mkdir
* move (mv, rename, ren)
* propdel (pdel, pd)
* propedit (pedit, pe)
* propget (pget, pg)
* proplist (plist, pl)
* propset (pset, ps)
* resolved
* revert
* status (stat, st)
* switch (sw)
* @param string $cmd
* @param string $param
*/
public function doCmd($cmd, $param = ''){
chdir($this->targetPath);
$cmd = "{$cmd} {$param}";
$result = $this->shell($cmd);
return $this->result($result);
}
/**
* Error message last time
*
* @return string error message
*/
public function error(){
return $this->error;
}
/**
* Format the result handle
*
* @param string $result result string
* @return string
*/
private function result($result){
if($result === false){
return false;
}
foreach(explode("\n", $result) as $line){
$line = trim($line);
$this->retLine($line);
}
return $this->retValue;
}
private function retLine($line){
$line = strtolower($line);
if(emptyempty($line)){
return;
}
$retValue = array();
if(in_array($line, $this->shortTags)){
$retValue['a'] = $line;
$retValue['v'] = trim(substr($line, 2));
}else{
preg_match('/(+)/', $line, $match);
$num = intval($match);
if($num > 0){
$retValue['a'] = 'v';
$retValue['v'] = $num;
}
}
$this->retValue[] = $retValue;
}
/**
* Get svn file version from result line
*
* @param string $line result line
* @return mixed version number or false if on error
*/
private function getVersionByLine($line){
$line = trim(strtolower($line));
if(preg_match('/(+)/', $line, $match)){
return $match;
}
return false;
}
/**
* Exec shell command
*
* @access private
* @param string $cmd command to be executed
* @return string result string should been displayed on stdout,
* @return return false if on error
*/
private function shell($cmd){
$opts = '';
foreach($this->opts as $key => $item){
if(!emptyempty($item)){
$opts .= "--{$key} {$item} ";
}
}
$result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);
if($this->isResultError()){
return false;
}
return $result;
}
/**
* Check if on error
*
* @param string $result shell result string
* @return boolen
*/
private function isResultError(){
$this->error = file_get_contents($this->errorfile);
if(emptyempty($this->error)){
return false;
}
return true;
}
}
?> 谢谢分享
页:
[1]