PHP头条
热点:

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


URI提供了很多帮你对uri_string分段分割的方法,你可以很轻松的得到uri中某一段。如:

$this->uri->segment(n)

$this->uri->rsegment(n)

$this->uri->slash_segment(n)

$this->uri->slash_rsegment(n)

$this->uri->uri_to_assoc(n)


$this->uri->ruri_to_assoc(n)


 等等。
config =& load_class('Config', 'core');
		log_message('debug', "URI Class Initialized");
	}


	//获取uri_string
	function _fetch_uri_string()
	{
                //$this->config->item('uri_protocol')是获取config.php中uri_protocol的配置,AUTO为默认
		if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
		{
			// 命令行方式执行
			if (php_sapi_name() == 'cli' or defined('STDIN'))
			{
				$this->_set_uri_string($this->_parse_cli_args());
				return;
			}
			// REQUEST_URI方式,绝大部分情况都能获取
			if ($uri = $this->_detect_uri())
			{
				$this->_set_uri_string($uri);
				return;
			}

			// PATH_INFO方式
			$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
			if (trim($path, '/') != '' && $path != "/".SELF)
			{
				$this->_set_uri_string($path);
				return;
			}

			// QUERY_STRING方式
			$path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
			if (trim($path, '/') != '')
			{
				$this->_set_uri_string($path);
				return;
			}

			// 尝试最后一种方式,通过$_GET获取键名
			if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
			{
				$this->_set_uri_string(key($_GET));
				return;
			}

			// 如果还没获取到uri_string ,只能返回空了
			$this->uri_string = '';
			return;
		}
                //其实下面很多都是把上面的东西重写了,这是根据用户在config.php中配置的
		$uri = strtoupper($this->config->item('uri_protocol'));
                //若为REQUEST_URI方式
		if ($uri == 'REQUEST_URI')
		{
			$this->_set_uri_string($this->_detect_uri());
			return;
		}
		elseif ($uri == 'CLI')
		{
			$this->_set_uri_string($this->_parse_cli_args());
			return;
		}

		$path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
		$this->_set_uri_string($path);
	}

	// --------------------------------------------------------------------

	//就是给uri_string赋值
	function _set_uri_string($str)
	{
		// 防止在ASCII字符之间插入空字符,如Java\0script.
		$str = remove_invisible_characters($str, FALSE);

		// If the URI contains only a slash we'll kill it
		$this->uri_string = ($str == '/') ? '' : $str;
	}

	// --------------------------------------------------------------------

	//检测URI
	private function _detect_uri()
	{
                //$_SERVER['REQUEST_URI']和$_SERVER['SCRIPT_NAME']两者都存在才可使用
		if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
		{
			return '';
		}

		$uri = $_SERVER['REQUEST_URI'];
                //去掉相同的部分,剩下有用的uri部分
		if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
		{
			$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
		}
		elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
		{
			$uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
		}

		//允许?/welcome/index这种格式
		if (strncmp($uri, '?/', 2) === 0)
		{
			$uri = substr($uri, 2);
		}
		$parts = preg_split('#\?#i', $uri, 2);
		$uri = $parts[0];
		if (isset($parts[1]))
		{
			$_SERVER['QUERY_STRING'] = $parts[1];
			parse_str($_SERVER['QUERY_STRING'], $_GET);
		}
		else
		{
			$_SERVER['QUERY_STRING'] = '';
			$_GET = array();
		}

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

		$uri = parse_url($uri, PHP_URL_PATH);

		//做最后的处理返回uri
		return str_replace(array('//', '../'), '/', trim($uri, '/'));
	}

	// --------------------------------------------------------------------

	//解析命令行方式参数
	private function _parse_cli_args()
	{
		$args = array_slice($_SERVER['argv'], 1);

		return $args ? '/' . implode('/', $args) : '';
	}

	// --------------------------------------------------------------------

	//过滤不合法的url字符,允许的uri是你的配置$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
	function _filter_uri($str)
	{
		if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
		{
			if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str))
			{
				show_error('The URI you submitted has disallowed characters.', 400);
			}
		}

		// Convert programatic characters to entities
		$bad	= array('$',		'(',		')',		'%28',		'%29');
		$good	= array('$',	'(',	')',	'(',	')');

		return str_replace($bad, $good, $str);
	}

	// --------------------------------------------------------------------

	//如果你配置了url_suffix,则去掉
	function _remove_url_suffix()
	{
		if  ($this->config->item('url_suffix') != "")
		{
			$this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);
		}
	}

	// --------------------------------------------------------------------

	//用/分隔uri_string,将结果保存到segments中
	function _explode_segments()
	{
		foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
		{
			// Filter segments for security
			$val = trim($this->_filter_uri($val));

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

	//这个是重建索引,将数组从下标1开始,这是为了你的使用习惯,如$this->uri->segment(1)就是获取第一段
	function _reindex_segments()
	{
		array_unshift($this->segments, NULL);
		array_unshift($this->rsegments, NULL);
		unset($this->segments[0]);
		unset($this->rsegments[0]);
	}

	// --------------------------------------------------------------------

	//获取uri中的一个片段
	function segment($n, $no_result = FALSE)
	{
		return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
	}

	// --------------------------------------------------------------------

	//返回确定路由后的一个uri片段
	function rsegment($n, $no_result = FALSE)
	{
		return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
	}

	
	function uri_to_assoc($n = 3, $default = array())
	{
		return $this->_uri_to_assoc($n, $default, 'segment');
	}
	function ruri_to_assoc($n = 3, $default = array())
	{
		return $this->_uri_to_assoc($n, $default, 'rsegment');
	}
	function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
	{
		if ($which == 'segment')
		{
			$total_segments = 'total_segments';
			$segment_array = 'segment_array';
		}
		else
		{
			$total_segments = 'total_rsegments';
			$segment_array = 'rsegment_array';
		}

		if ( ! is_numeric($n))
		{
			return $default;
		}

		if (isset($this->keyval[$n]))
		{
			return $this->keyval[$n];
		}

		if ($this->$total_segments() < $n)
		{
			if (count($default) == 0)
			{
				return array();
			}

			$retval = array();
			foreach ($default as $val)
			{
				$retval[$val] = FALSE;
			}
			return $retval;
		}

		$segments = array_slice($this->$segment_array(), ($n - 1));

		$i = 0;
		$lastval = '';
		$retval  = array();
		foreach ($segments as $seg)
		{
			if ($i % 2)
			{
				$retval[$lastval] = $seg;
			}
			else
			{
				$retval[$seg] = FALSE;
				$lastval = $seg;
			}

			$i++;
		}

		if (count($default) > 0)
		{
			foreach ($default as $val)
			{
				if ( ! array_key_exists($val, $retval))
				{
					$retval[$val] = FALSE;
				}
			}
		}

		// Cache the array for reuse
		$this->keyval[$n] = $retval;
		return $retval;
	}

	//很明显,它是将数组中的信息翻转成uri_string
	function assoc_to_uri($array)
	{
		$temp = array();
		foreach ((array)$array as $key => $val)
		{
			$temp[] = $key;
			$temp[] = $val;
		}

		return implode('/', $temp);
	}

        //通过第二个参数看是否给uri前后加上“/”线
	function slash_segment($n, $where = 'trailing')
	{
		return $this->_slash_segment($n, $where, 'segment');
	}

	function slash_rsegment($n, $where = 'trailing')
	{
		return $this->_slash_segment($n, $where, 'rsegment');
	}
	function _slash_segment($n, $where = 'trailing', $which = 'segment')
	{
		$leading	= '/';
		$trailing	= '/';

		if ($where == 'trailing')
		{
			$leading	= '';
		}
		elseif ($where == 'leading')
		{
			$trailing	= '';
		}

		return $leading.$this->$which($n).$trailing;
	}

	// --------------------------------------------------------------------
        //返回uri片段数组
	function segment_array()
	{
		return $this->segments;
	}
	function rsegment_array()
	{
		return $this->rsegments;
	}

	//计算uri片段的个数
	function total_segments()
	{
		return count($this->segments);
	}

	function total_rsegments()
	{
		return count($this->rsegments);
	}

	// --------------------------------------------------------------------

	//返回uri_string
	function uri_string()
	{
		return $this->uri_string;
	}
	function ruri_string()
	{
		return '/'.implode('/', $this->rsegment_array());
	}

}

www.phpzy.comtrue/phpkj/7952.htmlTechArticleCI框架源码完全分析之核心文件URI.php URI提供了很多帮你对uri_string分段分割的方法,你可以很轻松的得到uri中某一段。如: $this->uri->segment( n ) $this->uri->rsegment( n ) $this->uri->slash_segment(...

相关文章

相关频道:

PHP之友评论

今天推荐