【运维管理】使用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.?> 谢谢分享 收藏收藏:lol 正好可以学习学习。 楼主想法很好,直接不行,间接也很好,死马当活马医!:victory: 有想法,了解了
页:
[1]