CI框架源码完全分析之核心文件(URI类)URI.php
2015-04-26 15:33
786 查看
URI.php–URI类提供了帮助你分割URI字符串的函数集合。如果你使用URI路由功能,那么你就可以通过分段来重新分发地址栏信息。
1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 2. class CI_URI { 3. 4. //缓存的URI分段数组 5. var $keyval = array(); 6. 7. //当前URI字符串 8. var $uri_string; 9. 10. //URI分段数组 11. var $segments = array(); 12. 13. //重新排列的URI数组 14. var $rsegments = array(); 15. 16. function __construct() 17. { 18. $this->config =& load_class('Config', 'core'); 19. log_message('debug', "URI Class Initialized"); 20. } 21. 22. 23. //获取URI字符串 24. function _fetch_uri_string() 25. { 26. if (strtoupper($this->config->item('uri_protocol')) == 'AUTO') 27. { 28. // Is the request coming from the command line? 29. if (php_sapi_name() == 'cli' or defined('STDIN')) 30. { 31. $this->_set_uri_string($this->_parse_cli_args()); 32. return; 33. } 34. 35. // Let's try the REQUEST_URI first, this will work in most situations 36. if ($uri = $this->_detect_uri()) 37. { 38. $this->_set_uri_string($uri); 39. return; 40. } 41. 42. // Is there a PATH_INFO variable? 43. // Note: some servers seem to have trouble with getenv() so we'll test it two ways 44. $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); 45. if (trim($path, '/') != '' && $path != "/".SELF) 46. { 47. $this->_set_uri_string($path); 48. return; 49. } 50. 51. // No PATH_INFO?... What about QUERY_STRING? 52. $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); 53. if (trim($path, '/') != '') 54. { 55. $this->_set_uri_string($path); 56. return; 57. } 58. 59. // As a last ditch effort lets try using the $_GET array 60. if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '') 61. { 62. $this->_set_uri_string(key($_GET)); 63. return; 64. } 65. 66. // We've exhausted all our options... 4000 67. $this->uri_string = ''; 68. return; 69. } 70. 71. $uri = strtoupper($this->config->item('uri_protocol')); 72. 73. if ($uri == 'REQUEST_URI') 74. { 75. $this->_set_uri_string($this->_detect_uri()); 76. return; 77. } 78. elseif ($uri == 'CLI') 79. { 80. $this->_set_uri_string($this->_parse_cli_args()); 81. return; 82. } 83. 84. $path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri); 85. $this->_set_uri_string($path); 86. } 87. 88. //设置URI字符串 89. function _set_uri_string($str) 90. { 91. // Filter out control characters 92. $str = remove_invisible_characters($str, FALSE); 93. 94. // If the URI contains only a slash we'll kill it 95. $this->uri_string = ($str == '/') ? '' : $str; 96. } 97. 98. //检测URI字符串 99. private function _detect_uri() 100. { 101. if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME'])) 102. { 103. return ''; 104. } 105. 106. $uri = $_SERVER['REQUEST_URI']; 107. if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) 108. { 109. $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME'])); 110. } 111. elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) 112. { 113. $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); 114. } 115. 116. // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct 117. // URI is found, and also fixes the QUERY_STRING server var and $_GET array. 118. if (strncmp($uri, '?/', 2) === 0) 119. { 120. $uri = substr($uri, 2); 121. } 122. $parts = preg_split('#\?#i', $uri, 2); 123. $uri = $parts[0]; 124. if (isset($parts[1])) 125. { 126. $_SERVER['QUERY_STRING'] = $parts[1]; 127. parse_str($_SERVER['QUERY_STRING'], $_GET); 128. } 129. else 130. { 131. $_SERVER['QUERY_STRING'] = ''; 132. $_GET = array(); 133. } 134. 135. if ($uri == '/' || empty($uri)) 136. { 137. return '/'; 138. } 139. 140. $uri = parse_url($uri, PHP_URL_PATH); 141. 142. // Do some final cleaning of the URI and return it 143. return str_replace(array('//', '../'), '/', trim($uri, '/')); 144. } 145. 146. //解析命令行参数 147. private function _parse_cli_args() 148. { 149. $args = array_slice($_SERVER['argv'], 1); 150. 151. return $args ? '/' . implode('/', $args) : ''; 152. } 153. 154. //过滤URI字符串 155. function _filter_uri($str) 156. { 157. if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE) 158. { 159. // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards 160. // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern 161. if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str)) 162. { 163. show_error('The URI you submitted has disallowed characters.', 400); 164. } 165. } 166. 167. // Convert programatic characters to entities 168. $bad = array('$', '(', ')', '%28', '%29'); 169. $good = array('$', '(', ')', '(', ')'); 170. 171. return str_replace($bad, $good, $str); 172. } 173. 174. //删除URI后缀 175. function _remove_url_suffix() 176. { 177. if ($this->config->item('url_suffix') != "") 178. { 179. $this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string); 180. } 181. } 182. 183. //拆分URI字符串 184. function _explode_segments() 185. { 186. foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val) 187. { 188. // Filter segments for security 189. $val = trim($this->_filter_uri($val)); 190. 191. if ($val != '') 192. { 193. $this->segments[] = $val; 194. } 195. } 196. } 197. 198. //重新排序URI分段数组 199. function _reindex_segments() 200. { 201. array_unshift($this->segments, NULL); 202. array_unshift($this->rsegments, NULL); 203. unset($this->segments[0]); 204. unset($this->rsegments[0]); 205. } 206. 207. //从URI分段数组中取一部分 208. function segment($n, $no_result = FALSE) 209. { 210. return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n]; 211. } 212. 213. //从路由解析后的URI分段数组中取一部分 214. function rsegment($n, $no_result = FALSE) 215. { 216. return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n]; 217. } 218. 219. //从URI字符串或者路由解析后的字符串生成一个关联数组 220. function uri_to_assoc($n = 3, $default = array()) 221. { 222. return $this->_uri_to_assoc($n, $default, 'segment'); 223. } 224. //从路由解析后的字符串生成一个关联数组 225. function ruri_to_assoc($n = 3, $default = array()) 226. { 227. return $this->_uri_to_assoc($n, $default, 'rsegment'); 228. } 229. 230. //从URI字符串或者路由解析后的字符串生成一个关联数组 231. function _uri_to_assoc($n = 3, $default = array(), $which = 'segment') 232. { 233. if ($which == 'segment') 234. { 235. $total_segments = 'total_segments'; 236. $segment_array = 'segment_array'; 237. } 238. else 239. { 240. $total_segments = 'total_rsegments'; 241. $segment_array = 'rsegment_array'; 242. } 243. 244. if ( ! is_numeric($n)) 245. { 246. return $default; 247. } 248. 249. if (isset($this->keyval[$n])) 250. { 251. return $this->keyval[$n]; 252. } 253. 254. if ($this->$total_segments() < $n) 255. { 256. if (count($default) == 0) 257. { 258. return array(); 259. } 260. 261. $retval = array(); 262. foreach ($default as $val) 263. { 264. $retval[$val] = FALSE; 265. } 266. return $retval; 267. } 268. 269. $segments = array_slice($this->$segment_array(), ($n - 1)); 270. 271. $i = 0; 272. $lastval = ''; 273. $retval = array(); 274. foreach ($segments as $seg) 275. { 276. if ($i % 2) 277. { 278. $retval[$lastval] = $seg; 279. } 280. else 281. { 282. $retval[$seg] = FALSE; 283. $lastval = $seg; 284. } 285. 286. $i++; 287. } 288. 289. if (count($default) > 0) 290. { 291. foreach ($default as $val) 292. { 293. if ( ! array_key_exists($val, $retval)) 294. { 295. $retval[$val] = FALSE; 296. } 297. } 298. } 299. 300. // Cache the array for reuse 301. $this->keyval[$n] = $retval; 302. return $retval; 303. } 304. 305. //从关联数组生成一个URI字符串 306. function assoc_to_uri($array) 307. { 308. $temp = array(); 309. foreach ((array)$array as $key => $val) 310. { 311. $temp[] = $key; 312. $temp[] = $val; 313. } 314. 315. return implode('/', $temp); 316. } 317. 318. //获取路由解析后的URI分段数组中的某个元素 319. function slash_segment($n, $where = 'trailing') 320. { 321. return $this->_slash_segment($n, $where, 'segment'); 322. } 323. 324. //获取路由解析后的URI分段数组中的某个元素,并在其后添加正斜线 325. function slash_rsegment($n, $where = 'trailing') 326. { 327. return $this->_slash_segment($n, $where, 'rsegment'); 328. } 329. 330. //取得URI中的某一段并添加正斜线 331. function _slash_segment($n, $where = 'trailing', $which = 'segment') 332. { 333. $leading = '/'; 334. $trailing = '/'; 335. 336. if ($where == 'trailing') 337. { 338. $leading = ''; 339. } 340. elseif ($where == 'leading') 341. { 342. $trailing = ''; 343. } 344. 345. return $leading.$this->$which($n).$trailing; 346. } 347. 348. //URI分段数组 349. function segment_array() 350. { 351. return $this->segments; 352. } 353. 354. //路由解析后的URI分段数组 355. function rsegment_array() 356. { 357. return $this->rsegments; 358. } 359. 360. //URI分段数组长度 361. function total_segments() 362. { 363. return count($this->segments); 364. } 365. 366. //路由解析后的URI分段数组长度 367. function total_rsegments() 368. { 369. return count($this->rsegments); 370. } 371. 372. //获取整个URI字符串 373. function uri_string() 374. { 375. return $this->uri_string; 376. } 377. 378. 379. //获取整个路由后的URI字符串 380. function ruri_string() 381. { 382. return '/'.implode('/', $this->rsegment_array()); 383. } 384. 385. }
相关文章推荐
- CI框架源码完全分析之核心文件URI.php
- CI框架源码完全分析之核心文件(异常处理)Exceptions.php
- CI框架源码完全分析之核心文件(输入类)Input.php
- CI框架源码完全分析之核心文件Config.php(配置类)
- CI框架源码完全分析之核心文件(输入类)Input.php
- CI框架源码完全分析之核心文件Codeigniter.php
- CI框架源码完全分析之核心文件(安全类)Security.php
- CI框架源码完全分析之核心文件(输出类)Output.php
- CI框架源码完全分析之核心文件(输出类)Output.php
- CI框架源码完全分析之核心文件(UTF8类)Utf8.php
- CI框架源码完全分析之核心文件(装载器)Loader.php
- CI框架源码完全分析之核心文件(超级控制器)Controller.php
- CI框架源码完全分析之核心文件(钩子)Hooks.php
- CI框架源码完全分析之核心文件(模型)Model.php
- CI框架源码完全分析之核心文件(异常处理)Exceptions.php
- CI框架源码完全分析之核心文件(路由)Router.php
- CI框架源码完全分析之核心文件(安全类)Security.php
- CI框架源码完全分析之核心文件(路由)Router.php
- CI框架源码完全分析之核心文件(超级控制器)Controller.php
- CI框架源码完全分析之核心文件(钩子)Hooks.php