背景
早晨碰到一个有关base_url()
的小问题,遂追源码一通,如有错误请及时提出,共同进步
小问题,html中用到了<base>来指定基本url,加载如a、img、link、form会方便一点
手上项目前人这么写的当时就想着为什么不写成
然后资源就404了。印象中从哪看的base_url后会默认有/
过程
1.base_url()
有两个定义的地方,Core/config
中,helpers/url_helper
中
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()结果是最开始的时候不太懂html中写过如
当时不解为什么base_url()后会加/,并且也没把url传参入函数只是单独拼接,uri还是当参数传入好
echo base_url('a/b/')结果是