PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/core/controllers-shell/shell.controller.php

https://github.com/lewisliud/myqee
PHP | 326 lines | 221 code | 33 blank | 72 comment | 24 complexity | 2750cd215d36e85052498cceef0b66de MD5 | raw file
Possible License(s): LGPL-3.0, BSD-3-Clause
  1. <?php
  2. /**
  3. * SHELL 脚本基础控制器
  4. *
  5. * @author 呼吸二氧化碳 <jonwang@myqee.com>
  6. *
  7. */
  8. abstract class Core_Controller_Shell extends Controller
  9. {
  10. public function action_default()
  11. {
  12. $examples = array_diff(get_class_methods($this), get_class_methods(__CLASS__));
  13. # 获取方法的字符串最大长度
  14. $methods = array();
  15. $name_max_len = 0;
  16. foreach ($examples as $method)
  17. {
  18. if ($method ==__FUNCTION__) continue;
  19. if (strtolower(substr($method, 0, 7)) == 'action_')
  20. {
  21. $m = substr($method, 7);
  22. $methods[$m] = $m;
  23. $name_max_len = max(strlen($m), $name_max_len);
  24. }
  25. }
  26. $str = '';
  27. $str_usage = 'Usage: ';
  28. foreach ($methods as $method)
  29. {
  30. $ref_method = new ReflectionMethod( $this, 'action_' . $method );
  31. $parameters = $ref_method->getParameters();
  32. $str_usage .= str_pad($method, $name_max_len, ' ', STR_PAD_RIGHT);
  33. $comment = self::_parse_doc_comment( $ref_method->getDocComment());
  34. $str .= CRLF . CRLF . ' ' . $method . CRLF . ' comment : ' . $comment['title'][0] . CRLF . ' parameters: ';
  35. if ($parameters)
  36. {
  37. $tmpstr = array();
  38. $tmpparameter = array();
  39. $i = 0;
  40. $hava_l = 0;
  41. foreach ($parameters as $k => $parameter)
  42. {
  43. $tmpstr[] = ' $' . $parameter->name . ' ' . $comment['param'][$i];
  44. $tmpparameter[$k] = '$' . $parameter->getName();
  45. if ($parameter->isDefaultValueAvailable())
  46. {
  47. $hava_l ++;
  48. $tmpparameter[$k] = '[' . $tmpparameter[$k] . ' = ' . $parameter->getDefaultValue();
  49. }
  50. $i ++;
  51. }
  52. $str .= trim(implode(CRLF, $tmpstr));
  53. $str_usage .= ' [options] ' . '[' . implode(', ', $tmpparameter) . ']';
  54. if ($hava_l)
  55. {
  56. for($i = 0; $i < $hava_l; $i ++)
  57. {
  58. $str_usage .= ' ]';
  59. }
  60. }
  61. }
  62. else
  63. {
  64. $str .= '[no parameter]' . CRLF;
  65. }
  66. $str_usage .= CRLF . ' ';
  67. }
  68. $str_usage = trim($str_usage) . CRLF;
  69. echo $str_usage, $str, CRLF;
  70. }
  71. protected static function _parse_doc_comment($comment)
  72. {
  73. // Normalize all new lines to \n
  74. $comment = str_replace(array("\r\n", "\n"), "\n", $comment);
  75. // Remove the phpdoc open/close tags and split
  76. $comment = array_slice(explode("\n", $comment), 1, -1);
  77. // Tag content
  78. $param = array();
  79. foreach ($comment as $i => $line)
  80. {
  81. // Remove all leading whitespace
  82. $line = preg_replace('/^\s*\* ?/m', '', $line);
  83. // Search this line for a tag
  84. if (preg_match('/^@(\S+)(?:\s*(.+))?$/', $line, $matches))
  85. {
  86. // This is a tag line
  87. unset($comment[$i]);
  88. $name = $matches[1];
  89. $text = isset($matches[2]) ? $matches[2] : '';
  90. if ($text && $name == 'param')
  91. {
  92. // Add the tag
  93. $param[] = $text;
  94. }
  95. else
  96. {
  97. continue;
  98. }
  99. }
  100. else
  101. {
  102. // Overwrite the comment line
  103. $comment[$i] = (string)$line;
  104. }
  105. }
  106. return array('title' => $comment, 'param' => $param);
  107. }
  108. /**
  109. * 获取shell命令下参数
  110. *
  111. * 与getopt()具体相似的功能,区别:在命令行中如果执行 `php index.php default test -a=1 -b=c` 这样的命令时,通过getopt()会获取参数失败,而这个方法可以正确获得相应的参数
  112. *
  113. * **示例:**<br/>
  114. * 在默认项目Shell控制器中加入一个test控制器文件 ( `projects/default/controller_shell/test.controller.php` ) 内容为:
  115. *
  116. * <?php
  117. * class Controller_Test extends Controller_Shell
  118. * {
  119. * public function action_run()
  120. * {
  121. * $shortopts = "";
  122. * $shortopts .= "f:"; // 必须有值, 比如:-f myvalue,将会得到f=myvalue
  123. * $shortopts .= "v::"; // 可接受值, 比如:-v 则v=false,如果是-v=myvalue,则v=myvalue
  124. * $shortopts .= "abc"; // 不接受值, 比如:-a -v 则获取a=false,v=false,注意,这个并不是接受-abc的参数,而是分别可接受-a,-b,-c
  125. *
  126. * $longopts = array
  127. * (
  128. * "required:", // 必须有值, 比如:--required=abc
  129. * "optional::", // 可接受值, 比如:--optional 则获取 optional=false,--optional=abc,则是optional=abc
  130. * "option", // 不接受值, 比如:--option 则获取 option=false
  131. * "opt", // 同上
  132. * );
  133. *
  134. * $options = self::getopt($shortopts, $longopts);
  135. * var_dump($options);
  136. * }
  137. * }
  138. *
  139. * **通过 `php index.php default test run -f "value for f" -v -a --required value --optional="optional value" --option` 运行以上脚本会输出**
  140. *
  141. * array(6) {
  142. * ["f"]=> string(11) "value for f"
  143. * ["v"]=> bool(false)
  144. * ["a"]=> bool(false)
  145. * ["required"]=> string(5) "value"
  146. * ["optional"]=> string(14) "optional value"
  147. * ["option"]=> bool(false)
  148. * }
  149. *
  150. *
  151. * @link http://cn.php.net/getopt
  152. * @param string $options 但字符参数,只接受[a-zA-Z0-9]的参数,比如 -a, -h, -v=myvalue, -4 这样
  153. * @param array $global_options --参数,比如--test, --help, --v=abc 这样
  154. * @return array 返回获取到的参数的数组
  155. */
  156. public static function getopt($options, array $global_options = null)
  157. {
  158. $argv = $_SERVER['argv'];
  159. array_shift($argv);
  160. foreach($argv as $key => $item)
  161. {
  162. if ($item[0]=='-')
  163. {
  164. # 读取到第一个带-参数的值
  165. break;
  166. }
  167. unset($argv[$key]);
  168. }
  169. $argv = array_values($argv);
  170. $len = strlen($options);
  171. $my_options = array();
  172. $sl = 0;
  173. for($i=$len-1; $i>=0; $i--)
  174. {
  175. $key = $options[$i];
  176. if ($key==':')
  177. {
  178. $sl++;
  179. continue;
  180. }
  181. # 只接受a-zA-Z0-9
  182. if (preg_match('#[^a-zA-Z0-9]+#', $key))continue;
  183. if ($sl===0)
  184. {
  185. $my_options[$key] = 1;
  186. }
  187. elseif ($sl===1)
  188. {
  189. $my_options[$key.':'] = 1;
  190. }
  191. else
  192. {
  193. $my_options[$key.'::'] = 1;
  194. }
  195. $sl = 0;
  196. }
  197. $my_global_options = array();
  198. foreach($global_options as $item)
  199. {
  200. $my_global_options[$item] = 1;
  201. }
  202. $rs = array();
  203. foreach($argv as $k=>$item)
  204. {
  205. if (preg_match('#^\-(\-)?([a-z0-9\-]+)=(.*)$#i', $item, $m))
  206. {
  207. $key = $m[2];
  208. $value = $m[3];
  209. if ($m[1]=='-')
  210. {
  211. if (!isset($my_global_options[$key.'::']))
  212. {
  213. continue;
  214. }
  215. }
  216. else
  217. {
  218. if (!isset($my_options[$key.'::']))
  219. {
  220. continue;
  221. }
  222. }
  223. }
  224. elseif (preg_match('#^\-(\-)?([a-z0-9\-]+)$#i', $item, $m))
  225. {
  226. $key = $m[2];
  227. if ($m[1]=='-')
  228. {
  229. if (isset($my_global_options[$key]))
  230. {
  231. $value = false;
  232. }
  233. elseif (isset($my_global_options[$key.':']))
  234. {
  235. $value = $argv[$k+1];
  236. }
  237. else
  238. {
  239. continue;
  240. }
  241. }
  242. else
  243. {
  244. if (isset($my_options[$key]))
  245. {
  246. $value = false;
  247. }
  248. elseif (isset($my_options[$key.':']))
  249. {
  250. $value = $argv[$k+1];
  251. }
  252. elseif (isset($my_options[$key.'::']))
  253. {
  254. $value = false;
  255. }
  256. else
  257. {
  258. continue;
  259. }
  260. }
  261. }
  262. else
  263. {
  264. continue;
  265. }
  266. if (isset($rs[$key]))
  267. {
  268. $rs[$key] = (array)$rs[$key];
  269. $rs[$key][] = $value;
  270. }
  271. else
  272. {
  273. # 赋值
  274. $rs[$key] = $value;
  275. }
  276. }
  277. return $rs;
  278. }
  279. /**
  280. * 获取用户输入内容
  281. */
  282. public function input()
  283. {
  284. return trim(fgets(STDIN));
  285. }
  286. /**
  287. * 输出内容,会附加换行符
  288. */
  289. public function output($msg)
  290. {
  291. echo $msg . CRLF;
  292. }
  293. }