背景
早晨碰到一个有关base_url()
的小问题,遂追源码一通,如有错误请及时提出,共同进步
小问题,html中用到了<base>来指定基本url,加载如a、img、link、form会方便一点
手上项目前人这么写的
<base href="<?=base_url()?>assets/" target="_self">
<link href="global/plugins/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>
当时就想着为什么不写成
<base href="<?=base_url('assets')?>" target="_self">
然后资源就404了。印象中从哪看的base_url后会默认有/
然后就有了下面的了。
过程
1.base_url()
有两个定义的地方,Core/config
中,helpers/url_helper
中
2.url_helper
关键代码
if ( ! function_exists('base_url'))
{
function base_url($uri = '', $protocol = NULL)
{
//这里有点乱,结论就是加载到core/config中
return get_instance()->config->base_url($uri, $protocol);
}
}
3.core/Config
关键代码
class CI_Config {
public function __construct()
{
$this->config =& get_config();
//自动设置base_url的值如果用户没提供
if (empty($this->config['base_url']))
{
//正则匹配,如端口是8080就走这里
if (isset($_SERVER['HTTP_HOST']) && preg_match('/^((\[[0-9a-f:]+\])|(\d{1,3}(\.\d{1,3}){3})|[a-z0-9\-\.]+)(:\d+)?$/i', $_SERVER['HTTP_HOST']))
{
$base_url = (is_https() ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST']
.substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME'])));
}
else
{
//默认走这里
$base_url = 'http://localhost/';
}
$this->set_item('base_url', $base_url);
}
log_message('info', 'Config Class Initialized');
}
//设置配置
public function set_item($item, $value)
{
$this->config[$item] = $value;
}
}
多说一下,$_SERVER['HTTP_HOST']
,
'HTTP_HOST'
当前请求头中 Host: 项的内容,如果存在的话。
Http请求包头默认为
Host: localhost
接着说,我们的application/config中默认是这样的
$config['base_url'] = '';
过了config构造函数后
$config['base_url'] = 'http://localhost/';
接着追,core/Config.php
public function base_url($uri = '', $protocol = NULL)
{
$base_url = $this->slash_item('base_url');
//过了slash_item()返回的值还是http://localhost/
//一般不带协议,默认http
if (isset($protocol))
{
$base_url = $protocol.substr($base_url, strpos($base_url, '://'));
}
return $base_url.ltrim($this->_uri_string($uri), '/');
//返回的是指向一个资源的,排除了文件夹情况
}
public function slash_item($item)
{
if ( ! isset($this->config[$item]))
{
return NULL;
}
elseif (trim($this->config[$item]) === '')
{
return '';
}
//这时候config['base_url']值为http://localhost/
return rtrim($this->config[$item], '/').'/';
//rtrim — 删除字符串末端的空白字符,第二个参数为指定想要删除的字符列表
//防止原始字符串后有多个//,只保留一个
}
protected function _uri_string($uri)
{
//用户config文件中 $config['enable_query_strings'] = false
if ($this->item('enable_query_strings') === FALSE)
{
//如果是数组,分解
if (is_array($uri))
{
$uri = implode('/', $uri);
}
//去掉字符串两端的/,
//我自己之前最常见问题
//如 echo base_url('a/b/'),显示http://localhost/a/b
return trim($uri, '/');
}
elseif (is_array($uri))
{
return http_build_query($uri);
}
return $uri;
}
总结
走了这一遭,明白了一些碰见过的常见小问题
echo base_url()结果是http://localhost/XX/,最开始的时候不太懂html中写过如
<img src="<?php echo base_url().'/a/b'?>">
当时不解为什么base_url()后会加/,并且也没把url传参入函数只是单独拼接,uri还是当参数传入好
echo base_url('a/b/')结果是http://localhost/a/b