CI框架源码完全分析之核心文件(URI类)URI.php

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...  
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.    } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值