Base.php 8.7 KB

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