Home PHP Framework Laravel Introduction to ENV loading and reading under the Laravel framework

Introduction to ENV loading and reading under the Laravel framework

Oct 22, 2018 pm 02:17 PM
laravel php Source code analysis

This article brings you an introduction to loading and reading ENV under the Laravel framework. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Laravel will load the .env file in the project when it starts. It is often useful to have different configurations for different environments in which the application is running. For example, you may want to use the test MySQL database locally and want the project to automatically switch to the production MySQL database after going online. This article will introduce in detail the use of env files and source code analysis.

Use of Env files

Multi-environment env settings

The number of env files in a project is often the same as the number of environments in the project. If a project has development , test, and production environments, then there should be three environment configuration files in the project, .env.dev, .env.test, and .env.prod, corresponding to the environment. The configuration items in the three files should be exactly the same, and the specific configuration values ​​should be set according to the needs of each environment.

The next step is to enable the project to load different env files according to the environment. There are three specific methods, which can be chosen according to usage habits:

Set the APP_ENV environment variable fastcgi_param APP_ENV dev in the nginx configuration file of the environment;

Set the environment variables of the user running PHP on the server , for example, add export APP_ENV dev

in the www user’s /home/www/.bashrc and execute cp .env.dev .env

in the continuous integration task or deployment script of the deployment project. For the first two methods, Laravel will load the corresponding files .env.dev and .env.test based on the variable values ​​loaded by env('APP_ENV'). Specifically, as will be said in the source code later, the third method that is easier to understand is to overwrite the environment's configuration file into the .env file when deploying the project, so that there is no need to make additional settings in the environment's system and nginx.

Customized env file path and file name

The env file is placed in the root directory of the project by default. Laravel provides users with a custom ENV file path or file function,

For example, if you want to customize the env path, you can use the useEnvironmentPath method of the Application instance in app.php in the bootstrap folder:

$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

$app->useEnvironmentPath('/customer/path')
Copy after login

If you want to customize the env file name, you can use the loadEnvironmentFrom method of the Application instance in app.php in the bootstrap folder:

$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

$app->loadEnvironmentFrom('customer.env')
Copy after login

Laravel loads ENV configuration

Laravel loads ENV in This is done in the LoadEnvironmentVariables phase of the bootstrap process before the framework handles the request.

Let's take a look at the source code of \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables to analyze how Laravel loads the configuration in env.

<?php
namespace Illuminate\Foundation\Bootstrap;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use Symfony\Component\Console\Input\ArgvInput;
use Illuminate\Contracts\Foundation\Application;
class LoadEnvironmentVariables
{
    /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        if ($app->configurationIsCached()) {
            return;
        }

        $this->checkForSpecificEnvironmentFile($app);

        try {
            (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
        } catch (InvalidPathException $e) {
            //
        }
    }

    /**
     * Detect if a custom environment file matching the APP_ENV exists.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    protected function checkForSpecificEnvironmentFile($app)
    {
        if ($app->runningInConsole() && ($input = new ArgvInput)->hasParameterOption('--env')) {
            if ($this->setEnvironmentFilePath(
                $app, $app->environmentFile().'.'.$input->getParameterOption('--env')
            )) {
                return;
            }
        }

        if (! env('APP_ENV')) {
            return;
        }

        $this->setEnvironmentFilePath(
            $app, $app->environmentFile().'.'.env('APP_ENV')
        );
    }

    /**
     * Load a custom environment file.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @param  string  $file
     * @return bool
     */
    protected function setEnvironmentFilePath($app, $file)
    {
        if (file_exists($app->environmentPath().'/'.$file)) {
            $app->loadEnvironmentFrom($file);

            return true;
        }

        return false;
    }
}
Copy after login

In its startup method bootstrap, Laravel will check whether the configuration has been cached and determine which env file should be applied. For the first two of the three methods of loading configuration files based on the environment mentioned above, because APP_ENV is set in the system or nginx environment variable, so Laravel will set the correct specific path of the configuration file according to the value of APP_ENV in the checkForSpecificEnvironmentFile method, such as .env.dev or .env.test, and for the third case, it is the default .env, for details, please refer to the checkForSpecificEnvironmentFile below and the source code of the two methods in the related Application:

protected function checkForSpecificEnvironmentFile($app)
{
    if ($app->runningInConsole() && ($input = new ArgvInput)->hasParameterOption('--env')) {
        if ($this->setEnvironmentFilePath(
            $app, $app->environmentFile().'.'.$input->getParameterOption('--env')
        )) {
            return;
        }
    }

    if (! env('APP_ENV')) {
        return;
    }

    $this->setEnvironmentFilePath(
        $app, $app->environmentFile().'.'.env('APP_ENV')
    );
}

namespace Illuminate\Foundation;
class Application ....
{

    public function environmentPath()
    {
        return $this->environmentPath ?: $this->basePath;
    }
    
    public function environmentFile()
    {
        return $this->environmentFile ?: '.env';
    }
}
Copy after login

After determining the path of the configuration file to be read, the next step is to load the env. Configured.

(new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
Copy after login

Laravel uses the PHP version of Dotenv vlucas/phpdotenv

class Dotenv
{
    public function __construct($path, $file = '.env')
    {
        $this->filePath = $this->getFilePath($path, $file);
        $this->loader = new Loader($this->filePath, true);
    }

    public function load()
    {
        return $this->loadData();
    }

    protected function loadData($overload = false)
    {
        $this->loader = new Loader($this->filePath, !$overload);

        return $this->loader->load();
    }
}
Copy after login

It relies on /Dotenv/Loader to load data:

class Loader
{
    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;
    }
}
Copy after login

When Loader reads the configuration, the readLinesFromFile function will Use the file function to read the configuration from the file into the array line by line, then exclude the comments starting with #, and call the setEnvironmentVariable method for the lines containing = in the content to configure the environment variables in the file lines into the project. :

namespace Dotenv;
class Loader
{
    public function setEnvironmentVariable($name, $value = null)
    {
        list($name, $value) = $this->normaliseEnvironmentVariable($name, $value);

        $this->variableNames[] = $name;

        // 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;
    }
    
    public function getEnvironmentVariable($name)
    {
        switch (true) {
            case array_key_exists($name, $_ENV):
                return $_ENV[$name];
            case array_key_exists($name, $_SERVER):
                return $_SERVER[$name];
            default:
                $value = getenv($name);
                return $value === false ? null : $value; // switch getenv default to null
        }
    }
}
Copy after login

<span style="font-family: 微软雅黑, Microsoft YaHei;">When Dotenv instantiates Loader, set the $immutable property of the Loader object to false. When Loader sets the variable, if the variable value is read through the getEnvironmentVariable method, then it will Skip setting this environment variable. So Dotenv will not overwrite existing environment variables by default. This is very important. For example, in the docker container orchestration file, we will set two environment variables for the Mysql container for the PHP application container</span><br>

    environment:
      - "DB_PORT=3306"
      - "DB_HOST=database"
Copy after login

After setting the environment variables in the container, even if the DB_HOST in the env file is homestead and is read using the env function, it will still be the value of the DB_HOST environment variable previously set in the container database (in docker The container link uses the service name by default. In the orchestration file, I set the service name of the mysql container to database, so the php container needs to connect to the mysql container through the database host). Because when we do automated testing in continuous integration, we usually test in the container, so it is very important that Dotenv does not overwrite existing environment variables. This way I can only set the value of the environment variable in the container to complete the test. There is no need to change the env file in the project, just deploy the project to the environment directly after the test is completed.

If you check that the environment variable does not exist, then Dotenv will set the environment variable to the environment through the PHP built-in function putenv, and also store it in the two global variables $_ENV and $_SERVER.

Read env configuration in the project

In the Laravel application, you can use the env() function to read the value of the environment variable, such as obtaining the HOST of the database:

env('DB_HOST`, 'localhost');
Copy after login

The second value passed to the env function is the "default value". If no environment variable exists for the given key, this value will be used.

Let’s take a look at the source code of the env function:

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 (strlen($value) > 1 && Str::startsWith($value, '"') && Str::endsWith($value, '"')) {
        return substr($value, 1, -1);
    }

    return $value;
}
Copy after login

It reads environment variables directly through the PHP built-in function getenv.

We saw that when loading configuration and reading configuration, two functions putenv and getenv are used. The environment variables set by putenv only survive during the request, and the previous settings of the environment will be restored after the request ends. Because if the variables_order configuration item in php.ini becomes GPCS and does not contain E, then the environment variables cannot be read through $_ENV in the PHP program, so putenv is used to dynamically set the environment variables so that developers do not need to pay attention to the server configuration. Moreover, the environment variables configured for the running user on the server will be shared with all processes started by the user, which cannot protect private environment variables such as DB_PASSWORD and API_KEY well. Therefore, this configuration can be better protected with putenv settings. For these configuration information, the getenv method can obtain the system's environment variables and the environment variables dynamically set by putenv.

The above is the detailed content of Introduction to ENV loading and reading under the Laravel framework. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1670
14
PHP Tutorial
1276
29
C# Tutorial
1256
24
What happens if session_start() is called multiple times? What happens if session_start() is called multiple times? Apr 25, 2025 am 12:06 AM

Multiple calls to session_start() will result in warning messages and possible data overwrites. 1) PHP will issue a warning, prompting that the session has been started. 2) It may cause unexpected overwriting of session data. 3) Use session_status() to check the session status to avoid repeated calls.

Composer: Aiding PHP Development Through AI Composer: Aiding PHP Development Through AI Apr 29, 2025 am 12:27 AM

AI can help optimize the use of Composer. Specific methods include: 1. Dependency management optimization: AI analyzes dependencies, recommends the best version combination, and reduces conflicts. 2. Automated code generation: AI generates composer.json files that conform to best practices. 3. Improve code quality: AI detects potential problems, provides optimization suggestions, and improves code quality. These methods are implemented through machine learning and natural language processing technologies to help developers improve efficiency and code quality.

What is the significance of the session_start() function? What is the significance of the session_start() function? May 03, 2025 am 12:18 AM

session_start()iscrucialinPHPformanagingusersessions.1)Itinitiatesanewsessionifnoneexists,2)resumesanexistingsession,and3)setsasessioncookieforcontinuityacrossrequests,enablingapplicationslikeuserauthenticationandpersonalizedcontent.

What is the difference between php framework laravel and yii What is the difference between php framework laravel and yii Apr 30, 2025 pm 02:24 PM

The main differences between Laravel and Yii are design concepts, functional characteristics and usage scenarios. 1.Laravel focuses on the simplicity and pleasure of development, and provides rich functions such as EloquentORM and Artisan tools, suitable for rapid development and beginners. 2.Yii emphasizes performance and efficiency, is suitable for high-load applications, and provides efficient ActiveRecord and cache systems, but has a steep learning curve.

What database versions are compatible with the latest Laravel? What database versions are compatible with the latest Laravel? Apr 25, 2025 am 12:25 AM

The latest version of Laravel10 is compatible with MySQL 5.7 and above, PostgreSQL 9.6 and above, SQLite 3.8.8 and above, SQLServer 2017 and above. These versions are chosen because they support Laravel's ORM features, such as the JSON data type of MySQL5.7, which improves query and storage efficiency.

H5: Key Improvements in HTML5 H5: Key Improvements in HTML5 Apr 28, 2025 am 12:26 AM

HTML5 brings five key improvements: 1. Semantic tags improve code clarity and SEO effects; 2. Multimedia support simplifies video and audio embedding; 3. Form enhancement simplifies verification; 4. Offline and local storage improves user experience; 5. Canvas and graphics functions enhance the visualization of web pages.

How to use MySQL functions for data processing and calculation How to use MySQL functions for data processing and calculation Apr 29, 2025 pm 04:21 PM

MySQL functions can be used for data processing and calculation. 1. Basic usage includes string processing, date calculation and mathematical operations. 2. Advanced usage involves combining multiple functions to implement complex operations. 3. Performance optimization requires avoiding the use of functions in the WHERE clause and using GROUPBY and temporary tables.

Recommended Laravel's best expansion packs: 2024 essential tools Recommended Laravel's best expansion packs: 2024 essential tools Apr 30, 2025 pm 02:18 PM

The essential Laravel extension packages for 2024 include: 1. LaravelDebugbar, used to monitor and debug code; 2. LaravelTelescope, providing detailed application monitoring; 3. LaravelHorizon, managing Redis queue tasks. These expansion packs can improve development efficiency and application performance.

See all articles