您的位置:首页 > 编程语言 > PHP开发

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.    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  URI CI URI路由