- 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