.env 文件包含預設環境變數,我們還可自定義其他任何有效的變數,並可通過 調用 env() 或 $_SERVER 或 $_ENV 來獲取該變數。那麼env()是如何載入到這些變數的呢?在Lumen的vendor/laravel/lumen-framework/src/helpers.php中,我們 ...
.env 文件可自定義其他任何有效的環境變數,並可通過 調用 env() 或 $_SERVER 或 $_ENV 來獲取該變數。那麼env()是如何載入到這些變數的呢?在Lumen的vendor/laravel/lumen-framework/src/helpers.php中,我們可以發現env函數是這樣被定義的:
if (! function_exists('env')) { /** * Gets the value of an environment variable. Supports boolean, empty and null. * * @param string $key * @param mixed $default * @return mixed */ function env($key, $default = null) { $value = getenv($key); if ($value === false) { return value($default); } switch (strtolower($value)) { case 'true': case '(true)': return true; case 'false': case '(false)': return false; case 'empty': case '(empty)': return ''; case 'null': case '(null)': return; } if (Str::startsWith($value, '"') && Str::endsWith($value, '"')) { return substr($value, 1, -1); } return $value; } }
可見,env函數中調用了 getenv() 來讀取環境變數。我們又知道getenv()是PHP原生提供可讀取 $_SERVER 或 $_ENV 全局變數的函數API,.env文件中的環境變數為何可以通過getenv()來獲取呢?vlucas/phpdotenv 就是這個幕後功臣,在Lumen 或 Laravel 的vendor下可以找到她,如果要單獨下載她,去這裡 :https://github.com/vlucas/phpdotenv 。
在vlucas/phpdotenv/src/Loader.php文件中,我們可以看到.env被載入進一個數組,然後把每一行看作setter並調用setEnvironmentVariable()方法:
/** * Load `.env` file in given directory. * * @return array */ public function load() { $this->ensureFileIsReadable(); $filePath = $this->filePath; $lines = $this->readLinesFromFile($filePath); foreach ($lines as $line) { if (!$this->isComment($line) && $this->looksLikeSetter($line)) { $this->setEnvironmentVariable($line); } } return $lines; } /** * Read lines from the file, auto detecting line endings. * * @param string $filePath * * @return array */ protected function readLinesFromFile($filePath) { // Read file into an array of lines with auto-detected line endings $autodetect = ini_get('auto_detect_line_endings'); ini_set('auto_detect_line_endings', '1'); $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); ini_set('auto_detect_line_endings', $autodetect); return $lines; }
Loader::setEnvironmentVariable($name, $value = null) 的定義如下:
/** * Set an environment variable. * * This is done using: * - putenv, * - $_ENV, * - $_SERVER. * * The environment variable value is stripped of single and double quotes. * * @param string $name * @param string|null $value * * @return void */ public function setEnvironmentVariable($name, $value = null) { list($name, $value) = $this->normaliseEnvironmentVariable($name, $value); // Don't overwrite existing environment variables if we're immutable // Ruby's dotenv does this with `ENV[key] ||= value`. if ($this->immutable && $this->getEnvironmentVariable($name) !== null) { return; } // If PHP is running as an Apache module and an existing // Apache environment variable exists, overwrite it if (function_exists('apache_getenv') && function_exists('apache_setenv') && apache_getenv($name)) { apache_setenv($name, $value); } if (function_exists('putenv')) { putenv("$name=$value"); } $_ENV[$name] = $value; $_SERVER[$name] = $value; }
PHP dotenv 她是什麼?
Loads environment variables from .env to getenv(), $_ENV and $_SERVER automagically. This is a PHP version of the original Ruby dotenv.
Why .env?
You should never store sensitive credentials in your code. Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments – such as database credentials or credentials for 3rd party services – should be extracted from the code into environment variables. Basically, a .env file is an easy way to load custom configuration variables that your application needs without having to modify .htaccess files or Apache/nginx virtual hosts. This means you won't have to edit any files outside the project, and all the environment variables are always set no matter how you run your project - Apache, Nginx, CLI, and even PHP 5.4's built-in webserver. It's WAY easier than all the other ways you know of to set environment variables, and you're going to love it. . NO editing virtual hosts in Apache or Nginx . NO adding php_value flags to .htaccess files . EASY portability and sharing of required ENV values . COMPATIBLE with PHP's built-in web server and CLI runner