XSUtil.class.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /**
  3. * XSUtil 类定义文件
  4. *
  5. * @author hightman
  6. * @link http://www.xunsearch.com/
  7. * @copyright Copyright &copy; 2011 HangZhou YunSheng Network Technology Co., Ltd.
  8. * @license http://www.xunsearch.com/license/
  9. * @version $Id$
  10. */
  11. /**
  12. * XSUtil 工具程序通用代码
  13. *
  14. * @author hightman <hightman@twomice.net>
  15. * @version 1.0.0
  16. * @package XS.util
  17. */
  18. class XSUtil
  19. {
  20. private static $optind, $options = null;
  21. private static $charset = null;
  22. /**
  23. * 将项目参数转换为有效的 ini 文件
  24. * @param string $project 用户输入的项目参数
  25. * @return string 有效的 ini 配置文件路径
  26. */
  27. public static function toProjectIni($project)
  28. {
  29. if (!is_file($project)) {
  30. $appRoot = getenv('XS_APP_ROOT');
  31. if ($appRoot === false) {
  32. $appRoot = defined('XS_APP_ROOT') ? XS_APP_ROOT : dirname(__FILE__) . '/../app';
  33. }
  34. return $appRoot . '/' . $project . '.ini';
  35. } else {
  36. return $project;
  37. }
  38. }
  39. /**
  40. * 修正字符串至固定宽度
  41. * 其中一个全角符号、汉字的宽度为半角字符的 2 倍。
  42. * @param string $text 要修正的字符串
  43. * @param int $size 修正的目标宽度
  44. * @param string $pad 用于填充补足的字符
  45. * @return string
  46. */
  47. public static function fixWidth($text, $size, $pad = ' ')
  48. {
  49. for ($i = $j = 0; $i < strlen($text) && $j < $size; $i++, $j++) {
  50. if ((ord($text[$i]) & 0xe0) === 0xe0) {
  51. if (($size - $j) == 1) {
  52. break;
  53. }
  54. $j++;
  55. $i += 2;
  56. }
  57. }
  58. return substr($text, 0, $i) . str_repeat($pad, $size - $j);
  59. }
  60. /**
  61. * 设置输出、输入编码
  62. * 默认输出的中文编码均为 UTF-8
  63. * @param string $charset 期望得到的字符集
  64. */
  65. public static function setCharset($charset)
  66. {
  67. if ($charset !== null && strcasecmp($charset, 'utf8') && strcasecmp($charset, 'utf-8')) {
  68. self::$charset = $charset;
  69. ob_start(array(__CLASS__, 'convertOut'));
  70. }
  71. }
  72. /**
  73. * 把 UTF-8 字符串转换为用户编码
  74. * @param string $buf 要转换字符串
  75. * @return string 转换后的字符串
  76. */
  77. public static function convertOut($buf)
  78. {
  79. if (self::$charset !== null) {
  80. return XS::convert($buf, self::$charset, 'UTF-8');
  81. }
  82. return $buf;
  83. }
  84. /**
  85. * 把用户输入的字符串转换为 UTF-8 编码
  86. * @param string $buf 要转换字符串
  87. * @return string 转换后的字符串
  88. */
  89. public static function convertIn($buf)
  90. {
  91. if (self::$charset !== null) {
  92. return XS::convert($buf, 'UTF-8', self::$charset);
  93. }
  94. return $buf;
  95. }
  96. /**
  97. * 解析命令行参数
  98. * @param array $valued 需要附加值的参数列表
  99. * @return array 解析完的参数数组,未指定 - 开头的选项统一放入 '-' 的子数组
  100. */
  101. public static function parseOpt($valued = array())
  102. {
  103. $result = array('-' => array());
  104. $params = isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
  105. for ($i = 0; $i < count($params); $i++) {
  106. if ($params[$i] === '--') {
  107. for ($i = $i + 1; $i < count($params); $i++) {
  108. $result['-'][] = $params[$i];
  109. }
  110. break;
  111. } elseif ($params[$i][0] === '-') {
  112. $value = true;
  113. $pname = substr($params[$i], 1);
  114. if ($pname[0] === '-') {
  115. $pname = substr($pname, 1);
  116. if (($pos = strpos($pname, '=')) !== false) {
  117. $value = substr($pname, $pos + 1);
  118. $pname = substr($pname, 0, $pos);
  119. }
  120. } elseif (strlen($pname) > 1) {
  121. for ($j = 1; $j < strlen($params[$i]); $j++) {
  122. $pname = substr($params[$i], $j, 1);
  123. if (in_array($pname, $valued)) {
  124. $value = substr($params[$i], $j + 1);
  125. break;
  126. } elseif (($j + 1) != strlen($params[$i])) {
  127. $result[$pname] = true;
  128. }
  129. }
  130. }
  131. if ($value === true && in_array($pname, $valued) && isset($params[$i + 1])) {
  132. $value = $params[$i + 1];
  133. $i++;
  134. }
  135. $result[$pname] = $value;
  136. } else {
  137. $result['-'][] = $params[$i];
  138. }
  139. }
  140. self::$options = $result;
  141. self::$optind = 1;
  142. return $result;
  143. }
  144. /**
  145. * 取得命令行参数
  146. * 要求事先调用 parseOpt, 否则会自动以默认参数调用它。
  147. * @param string $short 短参数名
  148. * @param string $long 长参数名
  149. * @param bool $extra 是否补用默认顺序的参数
  150. * @return string 返回可用的参数值,若不存在则返回 null
  151. * @see parseOpt
  152. */
  153. public static function getOpt($short, $long = null, $extra = false)
  154. {
  155. if (self::$options === null) {
  156. self::parseOpt();
  157. }
  158. $value = null;
  159. $options = self::$options;
  160. if ($long !== null && isset($options[$long])) {
  161. $value = $options[$long];
  162. } elseif ($short !== null && isset($options[$short])) {
  163. $value = $options[$short];
  164. } elseif ($extra === true && isset($options['-'][self::$optind])) {
  165. $value = $options['-'][self::$optind];
  166. self::$optind++;
  167. }
  168. return $value;
  169. }
  170. /**
  171. * 刷新标准输出缓冲区
  172. */
  173. public static function flush()
  174. {
  175. flush();
  176. if (ob_get_level() > 0) {
  177. ob_flush();
  178. }
  179. }
  180. /**
  181. * 拷贝一个目录及其子目录文件
  182. */
  183. public static function copyDir($src, $dst)
  184. {
  185. if (!($dir = @dir($src)) || (!is_dir($dst) && !@mkdir($dst, 0755, true))) {
  186. return false;
  187. }
  188. while (($entry = $dir->read()) !== false) {
  189. if ($entry === '.' || $entry === '..') {
  190. continue;
  191. }
  192. $psrc = $src . DIRECTORY_SEPARATOR . $entry;
  193. $pdst = $dst . DIRECTORY_SEPARATOR . $entry;
  194. if (is_dir($pdst)) {
  195. self::copyDir($psrc, $pdst);
  196. } else {
  197. @copy($psrc, $pdst);
  198. }
  199. }
  200. $dir->close();
  201. return true;
  202. }
  203. }