Base.php 8.6 KB

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