CI框架源码解析8地址解析类文件URI.php

URI类主要处理地址字符串,将uri分解成对应的片段,存到segments数组中。querystring分解后存到$_GET数组,ROUTER路由类在之后的解析路由动作中,也主要依靠URI类的segments属性数组来获取当前上下文的请求URI信息。

 

$config['uri_protocol']配置不但决定以哪个函数处理URI,同时决定了从哪个全局变量里获取当前上下文的uri地址。对应关系是:

'REQUEST_URI'    使用 $_SERVER['REQUEST_URI']

'QUERY_STRING'   使用 $_SERVER['QUERY_STRING']

'PATH_INFO'      使用 $_SERVER['PATH_INFO']

 

那么这三个变量有什么区别呢?

$_SERVER['REQUEST_URI']获取的是url地址中主机头后面所有的字符

$_SERVER['QUERY_STRING']获取的url地址中"?"后面的部分

$_SERVER['PATH_INFO']获取的是url地址中脚本文 ($_SERVER['SCRIPT_NAME'])之后"?"之前的字符内容

 

1、构造函数_construct

 

功能流程:解析命令行或者请求url,获取querystring存入$_GET,uri存在segment数组

 

_parse_request_uri方法处理 AUTO,REQUEST_URI,PATH_INFO

_parse_query_string方法只处理QUERY_STRING

 

2、_parse_request_uri()方法

protected function _parse_request_uri()
	{
		if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
		{
			return '';
		}

        //从$_SERVER['REQUEST_URI']取值,解析成$uri和$query两个字符串,分别存储请求的路径和get请求参数
        $uri = parse_url('http://dummy'.$_SERVER['REQUEST_URI']);
		$query = isset($uri['query']) ? $uri['query'] : '';
		$uri = isset($uri['path']) ? $uri['path'] : '';

		if (isset($_SERVER['SCRIPT_NAME'][0]))
		{
			if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
			{
				$uri = (string) substr($uri, strlen($_SERVER['SCRIPT_NAME']));
			}
			elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
			{
				$uri = (string) substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
			}
		}

        //对于请求服务器的具体URI包含在查询字符串这种情况。
        //例如$uri以?/开头的 ,实际上if条件换种写法就是if(strncmp($uri, '?/', 2) === 0)),类似:
        //http://www.citest.com/index.php?/welcome/index
		if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0)
		{
			$query = explode('?', $query, 2);
			$uri = $query[0];
			$_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : '';
		}
		else
		{
			$_SERVER['QUERY_STRING'] = $query;
		}

		// 将查询字符串按照键名存入$_GET数组
		parse_str($_SERVER['QUERY_STRING'], $_GET);

		if ($uri === '/' OR $uri === '')
		{
			return '/';
		}

        //调用 _remove_relative_directory($uri)函数作安全处理
        //移除$uri中的../相对路径字符和反斜杠
        return $this->_remove_relative_directory($uri);
	}

3、_parse_query_string()方法

protected function _parse_query_string()
	{
		$uri = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');

		if (trim($uri, '/') === '')
		{
			return '';
		}
		elseif (strncmp($uri, '/', 1) === 0)
		{
			$uri = explode('?', $uri, 2);
			$_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : '';
			$uri = $uri[0];
		}

		parse_str($_SERVER['QUERY_STRING'], $_GET);

		return $this->_remove_relative_directory($uri);
	}

4、_set_uri_string($str) 解析$url填充到$this->segment数组中

 

 // 解析$url填充到$this->segments数组中
	protected function _set_uri_string($str)
	{
		// 移除$str不可见字符
		$this->uri_string = trim(remove_invisible_characters($str, FALSE), '/');

		if ($this->uri_string !== '')
		{
			// Remove the URL suffix, if present
			if (($suffix = (string) $this->config->item('url_suffix')) !== '')
			{
				$slen = strlen($suffix);

				if (substr($this->uri_string, -$slen) === $suffix)
				{
					$this->uri_string = substr($this->uri_string, 0, -$slen);
				}
			}

			$this->segments[0] = NULL;
			// Populate the segments array
			foreach (explode('/', trim($this->uri_string, '/')) as $val)
			{
				$val = trim($val);
				// Filter segments for security
				$this->filter_uri($val);

				if ($val !== '')
				{
					$this->segments[] = $val;
				}
			}

			unset($this->segments[0]);
		}
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值