Rumah rangka kerja php Laravel Laravel框架下ENV的加载和读取的介绍

Laravel框架下ENV的加载和读取的介绍

Oct 22, 2018 pm 02:17 PM
laravel php Analisis kod sumber

本篇文章给大家带来的内容是关于Laravel框架下ENV的加载和读取的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

Laravel在启动时会加载项目中的.env文件。对于应用程序运行的环境来说,不同的环境有不同的配置通常是很有用的。 例如,你可能希望在本地使用测试的Mysql数据库而在上线后希望项目能够自动切换到生产Mysql数据库。本文将会详细介绍 env 文件的使用与源码的分析。

Env文件的使用

多环境env的设置

项目中env文件的数量往往是跟项目的环境数量相同,假如一个项目有开发、测试、生产三套环境那么在项目中应该有三个.env.dev、.env.test、.env.prod三个环境配置文件与环境相对应。三个文件中的配置项应该完全一样,而具体配置的值应该根据每个环境的需要来设置。

接下来就是让项目能够根据环境加载不同的env文件了。具体有三种方法,可以按照使用习惯来选择使用:

在环境的nginx配置文件里设置APP_ENV环境变量fastcgi_param APP_ENV dev;

设置服务器上运行PHP的用户的环境变量,比如在www用户的/home/www/.bashrc中添加export APP_ENV dev

在部署项目的持续集成任务或者部署脚本里执行cp .env.dev .env

针对前两种方法,Laravel会根据env('APP_ENV')加载到的变量值去加载对应的文件.env.dev、.env.test这些。 具体在后面源码里会说,第三种比较好理解就是在部署项目时将环境的配置文件覆盖到.env文件里这样就不需要在环境的系统和nginx里做额外的设置了。

自定义env文件的路径与文件名

env文件默认放在项目的根目录中,laravel 为用户提供了自定义 ENV 文件路径或文件名的函数,

例如,若想要自定义 env 路径,可以在 bootstrap 文件夹中 app.php 中使用Application实例的useEnvironmentPath方法:

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

$app->useEnvironmentPath('/customer/path')
Salin selepas log masuk

若想要自定义 env 文件名称,就可以在 bootstrap 文件夹中 app.php 中使用Application实例的loadEnvironmentFrom方法:

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

$app->loadEnvironmentFrom('customer.env')
Salin selepas log masuk

Laravel 加载ENV配置

Laravel加载ENV的是在框架处理请求之前,bootstrap过程中的LoadEnvironmentVariables阶段中完成的。

我们来看一下\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables的源码来分析下Laravel是怎么加载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;
    }
}
Salin selepas log masuk

在他的启动方法bootstrap中,Laravel会检查配置是否缓存过以及判断应该应用那个env文件,针对上面说的根据环境加载配置文件的三种方法中的头两种,因为系统或者nginx环境变量中设置了APP_ENV,所以Laravel会在checkForSpecificEnvironmentFile方法里根据 APP_ENV的值设置正确的配置文件的具体路径, 比如.env.dev或者.env.test,而针对第三中情况则是默认的.env, 具体可以参看下面的checkForSpecificEnvironmentFile还有相关的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';
    }
}
Salin selepas log masuk

判断好后要读取的配置文件的路径后,接下来就是加载env里的配置了。

(new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
Salin selepas log masuk

Laravel使用的是Dotenv的PHP版本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();
    }
}
Salin selepas log masuk

它依赖/Dotenv/Loader来加载数据:

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;
    }
}
Salin selepas log masuk

Loader读取配置时readLinesFromFile函数会用file函数将配置从文件中一行行地读取到数组中去,然后排除以#开头的注释,针对内容中包含=的行去调用setEnvironmentVariable方法去把文件行中的环境变量配置到项目中去:

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
        }
    }
}
Salin selepas log masuk

<span style="font-family: 微软雅黑, Microsoft YaHei;">Dotenv实例化Loader的时候把Loader对象的$immutable属性设置成了false,Loader设置变量的时候如果通过getEnvironmentVariable方法读取到了变量值,那么就会跳过该环境变量的设置。所以Dotenv默认情况下不会覆盖已经存在的环境变量,这个很关键,比如说在docker的容器编排文件里,我们会给PHP应用容器设置关于Mysql容器的两个环境变量</span><br>

    environment:
      - "DB_PORT=3306"
      - "DB_HOST=database"
Salin selepas log masuk

这样在容器里设置好环境变量后,即使env文件里的DB_HOST为homestead用env函数读取出来的也还是容器里之前设置的DB_HOST环境变量的值database(docker中容器链接默认使用服务名称,在编排文件中我把mysql容器的服务名称设置成了database, 所以php容器要通过database这个host来连接mysql容器)。因为用我们在持续集成中做自动化测试的时候通常都是在容器里进行测试,所以Dotenv不会覆盖已存在环境变量这个行为就相当重要这样我就可以只设置容器里环境变量的值完成测试而不用更改项目里的env文件,等到测试完成后直接去将项目部署到环境上就可以了。

如果检查环境变量不存在那么接着Dotenv就会把环境变量通过PHP内建函数putenv设置到环境中去,同时也会存储到$_ENV和$_SERVER这两个全局变量中。

在项目中读取env配置

在Laravel应用程序中可以使用env()函数去读取环境变量的值,比如获取数据库的HOST:

env('DB_HOST`, 'localhost');
Salin selepas log masuk

传递给 env 函数的第二个值是「默认值」。如果给定的键不存在环境变量,则会使用该值。

我们来看看env函数的源码:

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;
}
Salin selepas log masuk

它直接通过PHP内建函数getenv读取环境变量。

我们看到了在加载配置和读取配置的时候,使用了putenv和getenv两个函数。putenv设置的环境变量只在请求期间存活,请求结束后会恢复环境之前的设置。因为如果php.ini中的variables_order配置项成了 GPCS不包含E的话,那么php程序中是无法通过$_ENV读取环境变量的,所以使用putenv动态地设置环境变量让开发人员不用去关注服务器上的配置。而且在服务器上给运行用户配置的环境变量会共享给用户启动的所有进程,这就不能很好的保护比如DB_PASSWORD、API_KEY这种私密的环境变量,所以这种配置用putenv设置能更好的保护这些配置信息,getenv方法能获取到系统的环境变量和putenv动态设置的环境变量。

Atas ialah kandungan terperinci Laravel框架下ENV的加载和读取的介绍. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Laravel fasih orm dalam carian model separa Bangla) Laravel fasih orm dalam carian model separa Bangla) Apr 08, 2025 pm 02:06 PM

Pengambilan Model Laraveleloquent: Mudah mendapatkan data pangkalan data Eloquentorm menyediakan cara ringkas dan mudah difahami untuk mengendalikan pangkalan data. Artikel ini akan memperkenalkan pelbagai teknik carian model fasih secara terperinci untuk membantu anda mendapatkan data dari pangkalan data dengan cekap. 1. Dapatkan semua rekod. Gunakan kaedah semua () untuk mendapatkan semua rekod dalam jadual pangkalan data: USEAPP \ MODELS \ POST; $ POSTS = POST :: SEMUA (); Ini akan mengembalikan koleksi. Anda boleh mengakses data menggunakan gelung foreach atau kaedah pengumpulan lain: foreach ($ postsas $ post) {echo $ post->

Masa Depan PHP: Adaptasi dan Inovasi Masa Depan PHP: Adaptasi dan Inovasi Apr 11, 2025 am 12:01 AM

Masa depan PHP akan dicapai dengan menyesuaikan diri dengan trend teknologi baru dan memperkenalkan ciri -ciri inovatif: 1) menyesuaikan diri dengan pengkomputeran awan, kontena dan seni bina microservice, menyokong Docker dan Kubernetes; 2) memperkenalkan pengkompil JIT dan jenis penghitungan untuk meningkatkan prestasi dan kecekapan pemprosesan data; 3) Berterusan mengoptimumkan prestasi dan mempromosikan amalan terbaik.

Geospatial Laravel: Pengoptimuman peta interaktif dan sejumlah besar data Geospatial Laravel: Pengoptimuman peta interaktif dan sejumlah besar data Apr 08, 2025 pm 12:24 PM

Cecair memproses 7 juta rekod dan membuat peta interaktif dengan teknologi geospatial. Artikel ini meneroka cara memproses lebih dari 7 juta rekod menggunakan Laravel dan MySQL dan mengubahnya menjadi visualisasi peta interaktif. Keperluan Projek Cabaran Awal: Ekstrak Wawasan berharga menggunakan 7 juta rekod dalam pangkalan data MySQL. Ramai orang mula -mula mempertimbangkan bahasa pengaturcaraan, tetapi mengabaikan pangkalan data itu sendiri: Bolehkah ia memenuhi keperluan? Adakah penghijrahan data atau pelarasan struktur diperlukan? Bolehkah MySQL menahan beban data yang besar? Analisis awal: Penapis utama dan sifat perlu dikenalpasti. Selepas analisis, didapati bahawa hanya beberapa atribut yang berkaitan dengan penyelesaiannya. Kami mengesahkan kemungkinan penapis dan menetapkan beberapa sekatan untuk mengoptimumkan carian. Carian Peta Berdasarkan Bandar

PHP vs Python: Memahami Perbezaan PHP vs Python: Memahami Perbezaan Apr 11, 2025 am 12:15 AM

PHP dan Python masing -masing mempunyai kelebihan sendiri, dan pilihannya harus berdasarkan keperluan projek. 1.Php sesuai untuk pembangunan web, dengan sintaks mudah dan kecekapan pelaksanaan yang tinggi. 2. Python sesuai untuk sains data dan pembelajaran mesin, dengan sintaks ringkas dan perpustakaan yang kaya.

PHP dan Python: Membandingkan dua bahasa pengaturcaraan yang popular PHP dan Python: Membandingkan dua bahasa pengaturcaraan yang popular Apr 14, 2025 am 12:13 AM

PHP dan Python masing -masing mempunyai kelebihan mereka sendiri, dan memilih mengikut keperluan projek. 1.PHP sesuai untuk pembangunan web, terutamanya untuk pembangunan pesat dan penyelenggaraan laman web. 2. Python sesuai untuk sains data, pembelajaran mesin dan kecerdasan buatan, dengan sintaks ringkas dan sesuai untuk pemula.

Status Semasa PHP: Lihat trend pembangunan web Status Semasa PHP: Lihat trend pembangunan web Apr 13, 2025 am 12:20 AM

PHP tetap penting dalam pembangunan web moden, terutamanya dalam pengurusan kandungan dan platform e-dagang. 1) PHP mempunyai ekosistem yang kaya dan sokongan rangka kerja yang kuat, seperti Laravel dan Symfony. 2) Pengoptimuman prestasi boleh dicapai melalui OPCACHE dan NGINX. 3) Php8.0 memperkenalkan pengkompil JIT untuk meningkatkan prestasi. 4) Aplikasi awan asli dikerahkan melalui Docker dan Kubernet untuk meningkatkan fleksibiliti dan skalabiliti.

Laravel dan backend: Powering Web Application Logic Laravel dan backend: Powering Web Application Logic Apr 11, 2025 am 11:29 AM

Bagaimanakah Laravel memainkan peranan dalam logik backend? Ia memudahkan dan meningkatkan pembangunan backend melalui sistem penghalaan, eloquentorm, pengesahan dan kebenaran, acara dan pendengar, dan pengoptimuman prestasi. 1. Sistem penghalaan membolehkan definisi struktur URL dan logik pemprosesan permintaan. 2.eloquentorm memudahkan interaksi pangkalan data. 3. Sistem pengesahan dan kebenaran adalah mudah untuk pengurusan pengguna. 4. Acara dan pendengar melaksanakan struktur kod yang ditambah dengan longgar. 5. Pengoptimuman prestasi meningkatkan kecekapan aplikasi melalui caching dan beratur.

PHP: asas banyak laman web PHP: asas banyak laman web Apr 13, 2025 am 12:07 AM

Sebab mengapa PHP adalah timbunan teknologi pilihan untuk banyak laman web termasuk kemudahan penggunaannya, sokongan komuniti yang kuat, dan penggunaan yang meluas. 1) Mudah dipelajari dan digunakan, sesuai untuk pemula. 2) Mempunyai komuniti pemaju yang besar dan sumber yang kaya. 3) Digunakan secara meluas dalam platform WordPress, Drupal dan lain -lain. 4) Mengintegrasikan dengan ketat dengan pelayan web untuk memudahkan penggunaan pembangunan.

See all articles