Ligonsker's avatar

When are the .env variables added to the $_SERVER global variable?

Hello,

Earlier I did dd($_SERVER) and I saw all the variables from the .env there alongside other global server variables. Then I cleared the config using php artisan optimize:clear and they disappeared.

So when are they added there? Because I already used the website more times after the cache clearing, and it still didn't show up there after doing dd($_SERVER) again.

Thanks

0 likes
11 replies
LaryAI's avatar
Level 58

The .env variables are added to the $_SERVER global variable when the application is first booted up. This happens during the bootstrap process, which occurs before any requests are handled.

When you cleared the config using php artisan optimize:clear, the application was restarted, causing the .env variables to be loaded into the $_SERVER global variable again.

It's worth noting that the .env variables are not added to the $_SERVER global variable directly. Instead, they are loaded into the application's configuration, which is then used to populate the $_SERVER global variable.

If you want to access the .env variables directly in your code, you can use the env() function. For example:

$apiKey = env('API_KEY');
Snapey's avatar

Lary making stuff up again

NEVER access .env variables directly in your code. Load them in config files.

Ligonsker's avatar

@Snapey I know, I will not access .env directly, I'm just having issues with setting up chrome-php/chrome: https://github.com/chrome-php/chrome#using-different-chrome-executable

I set the CHROME_PATH env variable both in Windows System variables and in the .env file, then I checked with set command in Windows CMD that the variable is SET, but then Laravel just "swallows" this specific key, CHROME_PATH.

This is very weird, something in Laravel ignores this key

I am using XAMPP on Windows 11 with Laravel 10.10.1 and PHP 8.2.4

Snapey's avatar

@Ligonsker You should add a config entry to one of the config file, perhaps services.php

before the closing ] add;

chrome_path => env('CHROME_PATH'),

and then put CHROME_PATH="full path to file" in your env file.

Check it with artisan tinker

> config('services.chrome_path');

use it like

$browserFactory = new BrowserFactory(config('services.chrome_path'));
1 like
Ligonsker's avatar

@Snapey the problem is that I wanted to change the default somehow, if you see the source for the chrome-php/chrome that checks for the env variable:

    public function guessChromeBinaryPath(): string
    {
        if (\array_key_exists('CHROME_PATH', $_SERVER)) {
            return $_SERVER['CHROME_PATH'];
        }

        switch (($this->osFamily)()) {
            case 'Darwin':
                return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
            case 'Windows':
                return self::getFromRegistry() ?? '%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe';
            default:
                return null === self::shellExec('command -v google-chrome') ? 'chrome' : 'google-chrome';
        }
    }

So I wanted to use Browserfactory() without any args. But your solution is the best in case I can't figure out why it's ignoring CHROME_PATH because I would need to only change the path in a single place (which is the purpose for that environment variable in the first place so it's perfect solution)

Ligonsker's avatar

@Snapey At first I thought I should add it to the system's environment variables (In Windows for example), but it didn't work so then I changed it to the bottom of the .env file.

Now I know it's not good to read directly from the .env on Laravel, but I just checked against other variables there. I added variables at the bottom of the .env, then dd()'d the $_SERVER in the piece of code above:

  public function guessChromeBinaryPath(): string
    {
        dd($_SERVER); // <-- here
       
        if (\array_key_exists('CHROME_PATH', $_SERVER)) {
            return $_SERVER['CHROME_PATH'];
        }

        switch (($this->osFamily)()) {
            case 'Darwin':
                return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
            case 'Windows':
                return self::getFromRegistry() ?? '%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe';
            default:
                return null === self::shellExec('command -v google-chrome') ? 'chrome' : 'google-chrome';
        }
    }

It then showed me all the environment variables from the .env, except for the specific CHROME_PATH. It's like it's "deleting" it, for example I added the following to the bottom of the .env:

SOME_VAR1="VAL1"
CHROME_PATH="TEST"
SOME_VAR2="VAL2"

and the dd($_SERVER); output was:

"SOME_VAR1" => "VAL1"
"SOME_VAR2" => "VAL2"

completely ignoring CHROME_PATH (And CHROME_PATH only).

Now I will use your solution of reading from the config, but I'm just so curious, why it ignores specifically CHROME_PATH??

If I change it to : CHROME_PAT, it reads it:

// .env file:

SOME_VAR1="VAL1"
CHROME_PAT="TEST"
SOME_VAR2="VAL2"

the the dd($_SERVER) would be:

"SOME_VAR1" => "VAL1"
"CHROME_PAT" => "TEST"
"SOME_VAR2" => "VAL2"
Ligonsker's avatar

@Snapey nope I just tested it on a clean laravel 10 project: after having issues with this specific env variable name (CHROME_PATH), I thought maybe it has something to do with the package chrome-php/chrome so I made a clean laravel 10 project and simply address CHROME_PATH to the bottom of the .env then simply dd($_SERVER) in a test controller. And once again, it ignored only CHROME_PATH . So weird.

Snapey's avatar

@Ligonsker Works for me in a Laravel 10 App provided I don't cache config.

When config is cached, the .env file is not read.

1 like
Ligonsker's avatar

@Snapey ok I'll try to keep checking. Maybe it's xampp issue? I don't cache either and when I add variables they are added to the bottom, everything except CHROME_PATH

Please or to participate in this conversation.