Dynamically Setting Base URL in CodeIgniter 3
If you use CodeIgniter and you’re tired of making the mistake of forgetting to change your site’s base URL before moving it to your online server OR you just want to be free from the hassle of changing your base URL each time your IP changes (on localhost) OR you just want your site to run on multiple domains without creating separate config files for each, then this right here is what you need.
Be default, base URL is set in the config.php file like:
$config['base_url'] = "http://www.amirsanni.com/";
While this serves the purpose, we will be required to change it each time our domain name or IP address changes (assuming we are accessing it via IP), when the site is being accessed via HTTPS, with or without ‘www’ and might be problematic while accessing the site from different environments.
Before we begin, we need to be aware that our site can be accessed via a local server, a remote server (cloud) or Command Line Interface (CLI) and we must be able to determine which of the environments the site is being accessed in order to set the appropriate base URL.
If our site is being accessed from the CLI, we do not need to set a base URL, so we will just leave it blank. To detect if the environment is CLI, we will use codeIgniter’s inbuilt is_cli() function to check if our site is being accessed from the CLI.
if(is_cli()){
$config['base_url'] = '';
}
For the other two environments, we need to determine whether the user is accessing our site via HTTP or HTTPS and also if it is with or without ‘www’.
Using another codeIgniter’s inbuilt function is_https(), we can easily determine if our site is being accessed via HTTPS.
$protocol = is_https() ? "https://" : "http://";
For the host (e.g. www.amirsanni.com), we can get that using PHP’s HTTP_HOST key in the super global ‘$_SERVER’ array.
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : "";
With the above, $host will have a value such as www.example.com, abc.xyz etc.
If our site is being accessed from a local server, we can easily set the base url as shown below considering the fact that the host on a local server can either be ‘localhost’, ‘localhost:PORT’, ‘127.0.0.*’ or ‘192.168.*.*’:
if(stristr($host, "localhost") !== FALSE || (stristr($host, '192.168.') !== FALSE) || (stristr($host, '127.0.0') !== FALSE){
$config['base_url'] = $protocol.$host."/PROJECT_FOLDER_NAME/";
}
For cloud, we will need to have a list of allowed hosts for security (and other) reasons and only allow the base URL to be set to one of them. Our array must take the ‘www’ prefix into consideration.
$allowed_hosts = ['amirsanni.com', 'www.amirsanni.com'];$config['base_url'] = in_array($host, $allowed_hosts) ? $protocol.$host."/" : "we-do-not-recognise-this-host.com";
Combining the three, we have:
$protocol = is_https() ? "https://" : "http://";
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : "";if(is_cli()){
$config['base_url'] = '';
}else if(stristr($host, "localhost") !== FALSE || (stristr($host, '192.168.') !== FALSE) || (stristr($host, '127.0.0') !== FALSE){
$config['base_url'] = $protocol.$host."/PROJECT_FOLDER/";
}else{
$allowed_hosts = ['amirsanni.com', 'www.amirsanni.com']; $config['base_url'] = in_array($host, $allowed_hosts) ? $protocol.$host."/" : "we-do-not-recognise-this-host.com";
}
There you go.