- 论坛徽章:
- 0
|
【运维管理】使用PHP操作SVN基础类
我不想使用PECL包中php svn扩展,一方面对PHP版本有要求,另外一方面对svn代码包有限制,不过最严重的是:对服务器PHP环境的依赖。
一个基础的svn类,应该实现基本的svn操作,如:checkout、update、commit、copy(最常用到)
【目的】
作为一个码农,写出一个被众人使用的组件、类库总是一件令人兴奋的事情,另外,代码的重用性也提倡将某一个方面的操作使用代码封装。
在自动化软件管理中,将代码从svn获取到当前地点,然后再对代码进行部署,并且通过可视化界面对此流程进行管理,这是个不错的想法。另外,通过对svn的管理,实现对代码版本的管理也是一件很有意义的事情。定期去检查代码,然后通知管理员改动信息,都是很好的想法。
【流程】
我想过从svn的协议部分下手,太过复杂,想我几天内是没有办法把它弄完的。因此,通过PHP的shell_exec()下手是个不错的选择。
[php] view plaincopy- 01.$result = @shell_exec("svn {$opts}" . $cmd . ' 2> ' . $this->errorfile);
复制代码 通过php执行shell,可以有各种空间来进行扩展和使用,但是有如下几点需要注意:
【环境依赖】
依赖Linux环境,
对操作目录、临时目录有操作权限
如果是web环境,同时需要保证apache的执行者具有权限。
【错误处理】
在调用SHELL的时候,倘若svn出错(这是不可避免的),错误不会通过标准输出(STDOUT)输出,而是通过标准错误(STDERR)来输出,标准错误不会被PHP捕捉到,但是会被apache或者操作系统捕捉到,造成PHP执行失败和无法显示的问题。
在这里,我选择了利用shell将错误信息重定向到一个临时文件,然后去读取临时文件来判断执行时是否有错误发生。
[php] view plaincopy- 01. 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基本数据的目录(当然前提是有权限读取),可以通过设置来进行
[php] view plaincopy- 01. public function setOptions($options = array()){
- 02. $this->opts = array_merge($this->opts, $options);
- 03.}
复制代码 【最终】
通过执行测试 和 phpdoc生成文档,即可完成一个基础类的创建
【开闭原则】
也许你知道,也许也不知道,说实话,我对它的理解仅仅局限于字面上。
使每一个与你共事的同事了解开闭原则是一件很重要的事,它能帮助你编写更多可重用的代码类库。
开(对扩展开放)闭(对修改关闭)保证了代码的可重用性和可维护性。
最后,将整个类库贴上。
[php] view plaincopy- 01.<?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[0], $this->shortTags)){
- 220. $retValue['a'] = $line[0];
- 221. $retValue['v'] = trim(substr($line, 2));
- 222. }else{
- 223. preg_match('/([0-9]+)/', $line, $match);
- 224. $num = intval($match[0]);
- 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('/([0-9]+)/', $line, $match)){
- 242. return $match[0];
- 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.?>
复制代码 |
|