Search code examples
codeignitercodeigniter-4

How do nested variables within the .env file work in CodeIgniter 4


Under the "Nesting Variables" section in Codeigniter4 site:

"To save on typing, you can reuse variables that you’ve already specified in the file by wrapping the variable name within ${...}" link to CI nesting Variables section

example in the documentation:

BASE_DIR="/var/webroot/project-root"

CACHE_DIR="${BASE_DIR}/cache"

TMP_DIR="${BASE_DIR}/tmp"

I was trying to use the following

app.baseURL = 'http://localhost:8080/'

google.redirect = ${app.baseURL}Google

However, it's assigning it as a literal when print_r($_ENV)

[google.redirect] => ${app.baseURL}Google

I've tried using non-namespaced keys including BASE_DIR (per the example) and it keeps printing as a literal.

What's strange - When I use the following:

CI_ENVIRONMENT = development

google.redirect = ${CI_ENVIRONMENT}Google

The result when print_r is:

[CI_ENVIRONMENT] => development

[google.redirect] => developmentGoogle

My question is - What am I doing incorrectly and/or how should these be set/used correctly?

According to the documentation, I should be able to use any key within the .env file that was already assigned using

${somekeyinthisfile}


Solution

  • After a bit of looking, there is a more recent file up at https://github.com/codeigniter4/CodeIgniter4/blob/develop/system/Config/DotEnv.php with all the "other" changes...

    This was a Bug Fix. So get that file and you will be good to go.

    I am pretty sure that the intention wasn't to allow app.xxx settings to be used as variables as the documentation clearly shows, by not showing them being used. ( yes its 6am now ...)

    BUT it is your code to do with as you please...So if you want to use app.xxx as variables...

    The Only Thing missing is the DOT (.) in the regex

    If you look on Line 272 - system/Config/DotEnv.php inside method resolveNestedVariables() and add a . (dot) into the regex, that will make all your app.things work.

      $value = preg_replace_callback(
         '/\${([a-zA-Z0-9_.]+)}/',
         function ($matchedPatterns) use ($loader) {
    

    I have added a dot (.) at the end of the [a-zA-Z0-9_

    So
    '/\${([a-zA-Z0-9_]+)}/',

    becomes

    '/\${([a-zA-Z0-9_.]+)}/',