Base.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. <?php
  2. namespace Qii\Request\Url;
  3. abstract class Base
  4. {
  5. const VERSION = '1.2';
  6. /**
  7. * URL 模式
  8. *
  9. * @var String
  10. */
  11. protected $_mode = 'Normal';
  12. /**
  13. * 链接字符
  14. *
  15. * @var String
  16. */
  17. private $_symbol = '&';
  18. /**
  19. * 文件后缀
  20. *
  21. * @var String
  22. */
  23. private $_extenstion = '.html';
  24. /**
  25. * 允许设置的URL模式
  26. *
  27. * @var Array
  28. */
  29. private $_allowMode = array('Normal', 'Middle', 'Short');
  30. /**
  31. * 是否去掉文件名称,如果rewrite不在根目录的时候将此设为true,避免生成URL错误.
  32. *
  33. * @var Bool
  34. */
  35. private $_fileNameTrim = false;
  36. /**
  37. * URL中匹配到的参数
  38. */
  39. private $params = null;
  40. /**
  41. * 初始化模式
  42. * @param string $mode 模式
  43. */
  44. public function __construct($mode)
  45. {
  46. $this->checkMode($mode);
  47. $this->_mode = $mode;
  48. if (in_array($mode, array('Short', 'Middle'))) {
  49. $this->_symbol = '/';
  50. }
  51. $this->params = $this->getParams();
  52. }
  53. /**
  54. * 返回所有params参数
  55. *
  56. */
  57. public function params()
  58. {
  59. return $this->params;
  60. }
  61. /**
  62. * 根据给定的参数创建URL
  63. * @param Array $array {controller:controllerName, action : actionName}
  64. * @param string $fileName
  65. * @param string $extenstion
  66. * @param string $trimExtension
  67. * @return string
  68. */
  69. public function bulidURI($params, $fileName = '', $extenstion = '', $trimExtension = false)
  70. {
  71. $this->checkMode($this->_mode);
  72. if (empty($fileName)) {
  73. $fileName = $_SERVER['SCRIPT_NAME'];
  74. }
  75. if (sizeof($params) == 0) {
  76. return '';
  77. }
  78. //2012-03-25新增 path,如果path==$fileName就去掉path,从而避免多个rewrite的时候调用此方法生成的URL错误。
  79. $path = $this->getPathInfo();
  80. //去掉文件名并保留路径 去掉加路径出现的bug
  81. if ($this->_fileNameTrim) {
  82. $fileName = rtrim(str_replace(basename($fileName), '', $fileName), "/");
  83. }
  84. $notAllowPath = array($fileName, "\\");
  85. if (in_array($path, $notAllowPath)) {
  86. $path = "";
  87. }
  88. $realPath = rtrim(str_replace('//', '/', $path . $fileName), '/');
  89. if ($this->_mode == 'normal') {
  90. return $fileName . '?' . $this->{$this->_mode}($params);
  91. }
  92. if (!empty($extenstion)) {
  93. return $realPath . $this->_symbol . $this->{$this->_mode}($params) . ($trimExtension ? '' : $extenstion);
  94. }
  95. return $realPath . $this->_symbol . $this->{$this->_mode}($array) . ($trimExtension ? '' : $this->_extenstion);
  96. }
  97. /**
  98. * 获取当前网址
  99. */
  100. public function getWebHost()
  101. {
  102. if (IS_CLI) return '';
  103. $prefix = 'http://';
  104. if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || $_SERVER['SERVER_PORT'] == 443) $prefix = 'https://';
  105. return $prefix . rtrim(rtrim(str_replace('//', '/', $_SERVER['HTTP_HOST']), '/'), "\\");
  106. }
  107. /**
  108. * 获取当前域名
  109. */
  110. public function getDomain()
  111. {
  112. return rtrim(rtrim(str_replace('//', '/', $_SERVER['HTTP_HOST']), '/'), "\\");
  113. }
  114. /**
  115. *
  116. * 获取当前页面URL
  117. */
  118. public function getCurrentURL()
  119. {
  120. if (IS_CLI) return '';
  121. return 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  122. }
  123. /**
  124. *
  125. * 获取当前页面的路径相关信息
  126. * @param String $path
  127. * @param String $index
  128. */
  129. public function getPathInfo($path = '', $index = 'dirname')
  130. {
  131. if (empty($path)) $path = $_SERVER['SCRIPT_NAME'];
  132. //Array ( [dirname] => /Qii [basename] => index.php [extension] => php [filename] => index )
  133. $pathInfo = pathinfo($path);
  134. $pathInfo['dirname'] = str_replace("\\", "/", $pathInfo['dirname']);
  135. if (!empty($index)) {
  136. return $pathInfo[$index];
  137. }
  138. return $pathInfo;
  139. }
  140. /**
  141. *
  142. * 获取当前路径
  143. * @param String $path
  144. */
  145. public function getPath($path = '')
  146. {
  147. if (empty($path)) {
  148. $path = $_SERVER['SCRIPT_NAME'];
  149. }
  150. return substr($path, 0, (strrpos($path, '/')));
  151. }
  152. /**
  153. *
  154. * 设置是否去掉文件名字
  155. * @param Bool $trim
  156. */
  157. public function setTrim($trim = false)
  158. {
  159. $this->_fileNameTrim = $trim;
  160. }
  161. /**
  162. * 设置文件后缀名字
  163. *
  164. * @param String $extenstion
  165. */
  166. public function setExtenstion($extenstion)
  167. {
  168. if (!empty($extenstion)) $this->_extenstion = $extenstion;
  169. }
  170. /**
  171. * 设置连接字符串
  172. *
  173. * @param String $symbol
  174. */
  175. public function setSymbol($symbol)
  176. {
  177. if (!empty($symbol)) $this->_symbol = $symbol;
  178. }
  179. /**
  180. * 设置URI模式
  181. *
  182. * @param String $mode
  183. */
  184. public function setMode($mode)
  185. {
  186. $this->checkMode($mode);
  187. $this->_mode = $mode;
  188. return $this;
  189. }
  190. /**
  191. * 获取本类中的私有属性
  192. *
  193. * @param String $key
  194. * @return Mix
  195. */
  196. public function get($key = null, $default= null)
  197. {
  198. if ($key === null) return $this->params;
  199. return isset($this->params[$key]) ? $this->params[$key] : $default;
  200. }
  201. /**
  202. * 获取POST数据
  203. */
  204. public function post($name = null, $default = null)
  205. {
  206. if ($name === null) return $_POST;
  207. return isset($_POST[$name]) ? $_POST[$name] : $default;
  208. }
  209. /**
  210. * Cli模式下数据的传输
  211. *
  212. * @param string $key
  213. */
  214. protected function CLIParams($key = '')
  215. {
  216. $argv = array();
  217. if (isset($_SERVER['argv'])) $argv = $_SERVER['argv'];
  218. //修正部分服务器Rewrite 后再加参数不识别的问题(直接进入命令行的模式)
  219. if ($argv && $_SERVER['PHP_SELF'] == $_SERVER['SCRIPT_NAME']) {
  220. if (count($argv) == 1) return;
  221. array_shift($argv);
  222. $args = (array)$this->parseArgs($argv[0]);
  223. //处理GET或POST方法 数据结构 key1=value1 key2=value2 键和值中间不能有空格
  224. if ($_SERVER['argc'] > 2) {
  225. for ($i = 1; $i < $_SERVER['argc'] - 1; $i++) {
  226. list($index, $val) = explode('=', $argv[$i], 2);
  227. $args[$index] = $val;
  228. }
  229. }
  230. if ($args && $key != '') {
  231. return isset($args[$key]) ? $args[$key] : '';
  232. }
  233. return $args;
  234. }
  235. }
  236. /**
  237. * 获取参数
  238. *
  239. * @param String $fileName
  240. * @param String $url
  241. * @param String $key
  242. * @return Mix
  243. */
  244. public function getParams($key = '', $url = '', $fileName = '')
  245. {
  246. if ($this->params != null) return $this->params;
  247. $this->checkMode($this->_mode);
  248. //如果是命令行模式
  249. if (IS_CLI) return $this->CLIParams($key);
  250. if ($this->_mode == 'Normal') {
  251. if (empty($key)) return $_GET;
  252. return $_GET[$key];
  253. }
  254. if (!isset($_SERVER['PATH_INFO'])) $_SERVER['PATH_INFO'] = '';
  255. if (empty($url)) {
  256. //修正Rewrite以指定目录开头的bug 将$url = $_SERVER['REQUEST_URI'];替换成以下的
  257. $url = (($_SERVER['PATH_INFO'] != '' && $_SERVER['PATH_INFO'] != '/') ? $_SERVER['PATH_INFO'] : $_SERVER['REQUEST_URI']);
  258. }
  259. if (empty($fileName)) {
  260. $fileName = $_SERVER['SCRIPT_NAME'];
  261. }
  262. //取fileName后边的内容
  263. $url = str_replace($fileName, "", $url);
  264. $param = parse_url($url);
  265. //如果到?号的URL则取query,没有?则取path的basename($path);
  266. if (isset($param['path']) && substr($param['path'], 0, 1) == '?') {
  267. //拆分字符
  268. if (empty($param['query'])) {
  269. return '';
  270. }
  271. $query = $param['query'];
  272. } else {
  273. $query = isset($param['path']) ? $param['path'] : '';
  274. }
  275. $query = $this->comparePath($query, $fileName);
  276. //添加系统扩展名到返回数组中 2011-10-14 15:26
  277. preg_match("/(.*)\.(.*)$/", $query, $extenstion);
  278. //去掉文件后缀名称,修改时间2010-09-03 22:33,以便指定任意后缀名。
  279. if (!isset($extenstion[2])) $extenstion[2] = '';
  280. $extenstion[2] = str_replace('/', '\/', $extenstion[2]);
  281. $query = preg_replace("/\.{$extenstion[2]}$/", "", $query);
  282. $paramArray = explode($this->_symbol, $query);
  283. $v = $this->decodeArgs($paramArray);
  284. //添加系统扩展名到返回数组中 2011-10-14 15:26
  285. $v['sysfileExtension'] = $extenstion[2];
  286. if ($_GET) $v = array_merge($v, $_GET);
  287. if ($key != '' || is_int($key)) {
  288. return $v[$key];
  289. }
  290. return $v;
  291. }
  292. /**
  293. * 对比转发文件的路径
  294. *
  295. * @param String $path
  296. * @param String $scriptName
  297. * @return String
  298. */
  299. public function comparePath($path, $f)
  300. {
  301. //去掉basename($f)再进行比较,比较的时候将字符串转换成小写;
  302. $basename = basename($f);
  303. $path = str_replace($basename, "", $path);
  304. $f = str_replace($basename, "", $f);
  305. //对比parseURL后的Path
  306. $pathArray = explode('/', ltrim(rtrim($path, '/'), '/'));
  307. $fArray = explode('/', ltrim(rtrim($f, '/'), '/'));
  308. $fCount = count($fArray);
  309. $tmpArray = array();
  310. $tmpArray = $pathArray;
  311. for ($i = 0; $i < $fCount; $i++) {
  312. if (strtolower($pathArray[$i]) != strtolower($fArray[$i])) {
  313. break;
  314. }
  315. array_shift($tmpArray);
  316. }
  317. return join("/", $tmpArray);
  318. }
  319. /**
  320. * 检查生成链接模式
  321. *
  322. * @param String $mode
  323. */
  324. public function checkMode($mode)
  325. {
  326. if (!in_array($mode, $this->_allowMode)) {
  327. throw new \Qii\Exceptions\Unsupport("链接模式错误,链接格式只能为 '<u><font color=\"green\">" . join("', '", $this->_allowMode) . "</font></u>',当前模式为 '<font color=\"red\">" . $mode . "</font>'", __LINE__);
  328. }
  329. }
  330. public function __call($method, $args)
  331. {
  332. //防止掉用不存在的方法
  333. }
  334. }