- 论坛徽章:
- 0
|
本帖最后由 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()下手是个不错的选择。
- [php] 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将错误信息重定向到一个临时文件,然后去读取临时文件来判断执行时是否有错误发生。- [php] 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基本数据的目录(当然前提是有权限读取),可以通过设置来进行- [php] 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生成文档,即可完成一个基础类的创建
【开闭原则】
也许你知道,也许也不知道,说实话,我对它的理解仅仅局限于字面上。
使每一个与你共事的同事了解开闭原则是一件很重要的事,它能帮助你编写更多可重用的代码类库。
开(对扩展开放)闭(对修改关闭)保证了代码的可重用性和可维护性。
最后,将整个类库贴上。
- [php] 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<[email]hufeng@staff.sina.com.cn[/email]>
- * @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[0], $this->shortTags)){
- $retValue['a'] = $line[0];
- $retValue['v'] = trim(substr($line, 2));
- }else{
- preg_match('/([0-9]+)/', $line, $match);
- $num = intval($match[0]);
- 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('/([0-9]+)/', $line, $match)){
- return $match[0];
- }
- 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;
- }
- }
-
- ?>
复制代码 |
|