feiyang10086 发表于 2012-01-20 20:16

【运维管理】使用PHP操作SVN基础类


【运维管理】使用PHP操作SVN基础类







我不想使用PECL包中php svn扩展,一方面对PHP版本有要求,另外一方面对svn代码包有限制,不过最严重的是:对服务器PHP环境的依赖。

一个基础的svn类,应该实现基本的svn操作,如:checkout、update、commit、copy(最常用到)

【目的】

作为一个码农,写出一个被众人使用的组件、类库总是一件令人兴奋的事情,另外,代码的重用性也提倡将某一个方面的操作使用代码封装。

在自动化软件管理中,将代码从svn获取到当前地点,然后再对代码进行部署,并且通过可视化界面对此流程进行管理,这是个不错的想法。另外,通过对svn的管理,实现对代码版本的管理也是一件很有意义的事情。定期去检查代码,然后通知管理员改动信息,都是很好的想法。

【流程】

我想过从svn的协议部分下手,太过复杂,想我几天内是没有办法把它弄完的。因此,通过PHP的shell_exec()下手是个不错的选择。




view plaincopy01.$result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);通过php执行shell,可以有各种空间来进行扩展和使用,但是有如下几点需要注意:

【环境依赖】

依赖Linux环境,

对操作目录、临时目录有操作权限

如果是web环境,同时需要保证apache的执行者具有权限。

【错误处理】

在调用SHELL的时候,倘若svn出错(这是不可避免的),错误不会通过标准输出(STDOUT)输出,而是通过标准错误(STDERR)来输出,标准错误不会被PHP捕捉到,但是会被apache或者操作系统捕捉到,造成PHP执行失败和无法显示的问题。

在这里,我选择了利用shell将错误信息重定向到一个临时文件,然后去读取临时文件来判断执行时是否有错误发生。




view plaincopy01.       private function shell($cmd){
02.    $opts = '';
03.    foreach($this->opts as $key => $item){
04.      if(!emptyempty($item)){
05.            $opts .= "--{$key} {$item} ";
06.      }
07.    }
08.    $result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);
09.    if($this->isResultError()){
10.      return false;
11.    }
12.    return $result;
13.} 【选项】

选项包括:svn的用户名和密码,或者存储svn基本数据的目录(当然前提是有权限读取),可以通过设置来进行




view plaincopy01.       public function setOptions($options = array()){
02.    $this->opts = array_merge($this->opts, $options);
03.}【最终】

通过执行测试 和 phpdoc生成文档,即可完成一个基础类的创建

【开闭原则】

也许你知道,也许也不知道,说实话,我对它的理解仅仅局限于字面上。

使每一个与你共事的同事了解开闭原则是一件很重要的事,它能帮助你编写更多可重用的代码类库。

开(对扩展开放)闭(对修改关闭)保证了代码的可重用性和可维护性。




最后,将整个类库贴上。




view plaincopy01.<?php
02./**
03. * For svn use by php
04. *
05. * This class allow you checkout svn files through web
06. * And allow you update files
07. * I hope in the later version, it can handle commit and other actions
08. *
09. * @example
10. * <code>
11. * $phpsvn = new phpsvn();
12. * $phpsvn->setOptions(array(
13. *'username' => 'yourname',
14. *'password' => 'yourpassword'
15. * ));
16. * $phpsvn->setPath($svnpath, $localpath);
17. * $r = $phpsvn->checkout();
18. * if($r === false){
19. *echo $phpsvn->error();
20. * }else{
21. *print_r($r);
22. * }
23. * </code>
24. * @author hufeng<hufeng@staff.sina.com.cn>
25. * @version v1.0
26. * @access sflib
27. * @package sflib
28. * @category phpsvn
29. * @copyright 2012-2013@copyright sflib
30. */
31.
32.
33.class phpsvn
34.{
35.    /**
36.   * svn command options
37.   *
38.   * @var array
39.   */
40.    private $opts = array(
41.      'username' => '',
42.      'password' => '',
43.      'config-dir' => '',///usr/home/finance/.subversion
44.    );
45.      
46.    /**
47.   * error log file
48.   *
49.   * Will not save data in this file
50.   * Just a tmp file store tmp error message
51.   * @var string
52.   */
53.    private $errorfile = '/tmp/phpsvn.err';
54.      
55.    /**
56.   * Error message
57.   *
58.   * If no error, error = ''
59.   * @var string
60.   */
61.    private $error = '';
62.      
63.    /**
64.   * The value to return
65.   *
66.   * @var array
67.   */
68.    private $retValue = array();
69.      
70.    /**
71.   * Svn path
72.   *
73.   * @var string
74.   */
75.    private $svnpath = '';
76.      
77.    /**
78.   * Local file path where file stored
79.   *
80.   * @var string
81.   */
82.    private $targetPath = '.';
83.      
84.    /**
85.   * actions tags
86.   *
87.   * @var array
88.   */
89.    private $shortTags = array('a', 'u', 'd');
90.      
91.    /**
92.   * Set opts of svn command
93.   *
94.   * allow opts:
95.   * username : your svn username
96.   * password : your svn password
97.   * config-dir : your execute user config dir
98.   * @param array $options
99.   */
100.    public function setOptions($options = array()){
101.      $this->opts = array_merge($this->opts, $options);
102.    }
103.      
104.    /**
105.   * Set svn path & localpath
106.   *
107.   * @param string $svnpath svn path
108.   * @param string $targetpath local path
109.   * @return void
110.   */
111.    public function setPath($svnpath, $targetpath = '.'){
112.      $this->svnpath = $svnpath;
113.      $this->targetPath = realpath($targetpath);
114.    }
115.      
116.    /**
117.   * update from server
118.   *
119.   * @return mixed array on success or false on error
120.   */
121.    public function update(){
122.      return $this->doCmd('up');
123.    }
124.      
125.    /**
126.   * commit file to server
127.   *
128.   * @return mixed array on success or false on error
129.   */
130.    public function commit(){
131.      return $this->doCmd('ci');
132.    }
133.      
134.    /**
135.   * Add file to svn
136.   *
137.   * @param string $file filename
138.   * @return mixed array on success or false on error
139.   */
140.    public function add($file){
141.      return $this->doCmd('add', $file);
142.    }
143.
144.    /**
145.   * Chectout file from svn to local
146.   *
147.   * @return mixed array on success or false on error
148.   */
149.    public function checkout(){
150.      return $this->doCmd('co', $this->svnpath);
151.      //Checked out revision 240772
152.    }
153.      
154.    /**
155.   * Execute command for svn
156.   *
157.   * support commands:add/checkout(co)/cleanup/commit(ci)/copy(cp)/delete(del,remove,rm)/diff(di)/update (up)
158.   * todo commands:export
159.   * help (?, h)
160.   * import
161.   * info
162.   * list (ls)
163.   * lock
164.   * log
165.   * merge
166.   * mkdir
167.   * move (mv, rename, ren)
168.   * propdel (pdel, pd)
169.   * propedit (pedit, pe)
170.   * propget (pget, pg)
171.   * proplist (plist, pl)
172.   * propset (pset, ps)
173.   * resolved
174.   * revert
175.   * status (stat, st)
176.   * switch (sw)
177.   * @param string $cmd
178.   * @param string $param
179.   */
180.    public function doCmd($cmd, $param = ''){
181.      chdir($this->targetPath);
182.      $cmd = "{$cmd} {$param}";
183.      $result = $this->shell($cmd);
184.      return $this->result($result);
185.    }
186.      
187.    /**
188.   * Error message last time
189.   *
190.   * @return string error message
191.   */
192.    public function error(){
193.      return $this->error;
194.    }
195.      
196.    /**
197.   * Format the result handle
198.   *
199.   * @param string $result result string
200.   * @return string
201.   */
202.    private function result($result){
203.      if($result === false){
204.            return false;
205.      }
206.      foreach(explode("\n", $result) as $line){
207.            $line = trim($line);
208.            $this->retLine($line);
209.      }
210.      return $this->retValue;
211.    }
212.      
213.    private function retLine($line){
214.      $line = strtolower($line);
215.      if(emptyempty($line)){
216.            return;
217.      }
218.      $retValue = array();
219.      if(in_array($line, $this->shortTags)){
220.            $retValue['a'] = $line;
221.            $retValue['v'] = trim(substr($line, 2));
222.      }else{
223.            preg_match('/(+)/', $line, $match);
224.            $num = intval($match);
225.            if($num > 0){
226.                $retValue['a'] = 'v';
227.                $retValue['v'] = $num;
228.            }
229.      }
230.      $this->retValue[] = $retValue;
231.    }
232.      
233.    /**
234.   * Get svn file version from result line
235.   *
236.   * @param string $line result line
237.   * @return mixed version number or false if on error
238.   */
239.    private function getVersionByLine($line){
240.      $line = trim(strtolower($line));
241.      if(preg_match('/(+)/', $line, $match)){
242.            return $match;
243.      }
244.      return false;
245.    }
246.    /**
247.   * Exec shell command
248.   *
249.   * @access private
250.   * @param string $cmd command to be executed
251.   * @return string result string should been displayed on stdout,
252.   * @return return false if on error
253.   */
254.    private function shell($cmd){
255.      $opts = '';
256.      foreach($this->opts as $key => $item){
257.            if(!emptyempty($item)){
258.                $opts .= "--{$key} {$item} ";
259.            }
260.      }
261.      $result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);
262.      if($this->isResultError()){
263.            return false;
264.      }
265.      return $result;
266.    }
267.      
268.    /**
269.   * Check if on error
270.   *
271.   * @param string $result shell result string
272.   * @return boolen
273.   */
274.    private function isResultError(){
275.      $this->error = file_get_contents($this->errorfile);
276.      if(emptyempty($this->error)){
277.            return false;
278.      }
279.      return true;
280.    }
281.}
282.
283.?>

清风鸟儿 发表于 2012-01-20 20:17

谢谢分享

lastfile 发表于 2012-01-22 11:12

收藏收藏:lol

kenny0716 发表于 2012-01-22 12:30

正好可以学习学习。

fengyun530 发表于 2012-01-22 23:01

楼主想法很好,直接不行,间接也很好,死马当活马医!:victory:

surpass_li 发表于 2012-01-29 11:06

有想法,了解了
页: [1]
查看完整版本: 【运维管理】使用PHP操作SVN基础类