【问题标题】:how to load different .env file for multiple domain in single laravel app?如何在单个 laravel 应用程序中为多个域加载不同的 .env 文件?
【发布时间】:2018-06-15 13:08:05
【问题描述】:

我想通过多个域访问单个 laravel 应用程序。

对于路由,我使用了 laravel 路由模式。

$appRoutes = function() {
     Route::group(['namespace'=>"Interface1"], function(){

     /** route for index page and User authentication pages **/
     Route::get('/', 'LoginController@showLoginForm')->name('login'); 
 });
};

Route::group(array('domain' => 'example1.com'), $appRoutes);
Route::group(array('domain' => 'example2.com'), $appRoutes);

现在每个域的 .env 我已经替换了 AppServiceProvider.php 注册方法中的配置变量值:

   if(isset($_SERVER['HTTP_HOST']) && !empty($_SERVER['HTTP_HOST']) ){ 
        if($_SERVER['HTTP_HOST']=='example1.com'){  
            $configArray = [
                'APP_NAME' => 'Application 1',
                'APP_URL'  =>  'http://example1.com', 
            ]; 
        }else{  
            $configArray = [
                'APP_NAME' => 'Application 2', 
                'APP_URL' =>  'http://example2.com, 
            ];  
        }  
        config($configArray);
    } 

但我仍然没有使用url(config('app.url'))获得正确的域网址

如何为每个域加载所有.env 变量覆盖?

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    对于当前的Laravel 7.x。在撰写本文时,您可以在 bootstrap/app.php 文件中的 return $app 语句之前添加以下代码。

    // bootstrap/app.php
    
    // ...
    
    /*
    |-----------------------------------------------
    | Load domain-specific .env file if it exists
    |-----------------------------------------------
    */
    
    if(isset($_SERVER['HTTP_HOST']) && !empty($_SERVER['HTTP_HOST'])){
        $domain = $_SERVER['HTTP_HOST'];
    }
    
    if (isset($domain)) {
        $dotenv = Dotenv\Dotenv::createImmutable(base_path(), '.env.'.$domain);
    
        try {
            $dotenv->load();
        } catch (\Dotenv\Exception\InvalidPathException $e) {
            // No custom .env file found for this domain
        }
    }
    
    // ...
    
    return $app;
    

    接下来,您应该为每个域创建一个.env 文件,格式如下:.env.example1.com.env.example2.com。对于缺少显式 .env 文件的域,您可以保留原始 .env 作为备用。

    对于 Laravel 5.x 或 Laravel 6.x,您可以从 original solution 找到更多信息。

    【讨论】:

    • 您好,在暂存和生产方面遇到问题,本地没问题。 $_SERVER['HTTP_HOST'] 总是返回 null。知道为什么以及如何解决吗?
    【解决方案2】:

    config() 设置配置设置,但不设置环境设置。

    您必须执行以下操作:

    if(isset($_SERVER['HTTP_HOST']) && !empty($_SERVER['HTTP_HOST']) ){ 
        if($_SERVER['HTTP_HOST']=='example1.com'){  
             $configArray = [
                'app.name' => 'Application 2', 
                'app.url' =>  'http://example2.com', 
            ];  ;
        }else{  
            $configArray = [
                'app.name' => 'Application 2', 
                'app.url' =>  'http://example2.com', 
            ];  
        }  
        config($configArray);
    } 
    

    然后您可以通过以下方式检索值:

    config("app.name");
    config("app.url");
    

    据我所知,没有办法在实际加载配置之前修改环境变量,因为在服务提供者注册之前加载配置并读取环境变量。

    还要注意使用HTTP_HOST,因为它是客户端设置的标头,可能不可靠。

    【讨论】:

      【解决方案3】:

      这里有一个简单的解决方案Laravel Multi Domain Package

      这个包允许单个 Laravel 安装使用多个 HTTP 域。

      在很多情况下,不同的客户在代码方面使用相同的应用程序,而不是在数据库、存储和配置方面。

      这个包提供了一种非常简单的方法来为每个这样的客户获取特定的 env 文件、特定的存储路径和特定的数据库。

      安装步骤

      添加 gecche/laravel-multidomain 作为 composer.json 的要求:

      {
          "require": {
              "gecche/laravel-multidomain": "4.*"
          }
      }
      

      使用 composer update 更新您的包或使用 composer install 安装。

      您也可以使用 composer require gecche/laravel-multidomain 添加包,然后指定您想要的版本(目前,dev-v1.1.* 是您最好的选择)。

      这个包需要在引导过程的一开始就在最小的 Laravel 核心函数集中覆盖对 HTTP 域的检测,以获取特定的环境文件。所以这个包比大多数 Laravel 包需要更多的配置步骤。

      安装步骤:

      通过修改 bootstrap/app.php 文件最顶部的以下几行来替换整个 Laravel 容器。

      //$app = new Illuminate\Foundation\Application(
      $app = new Gecche\Multidomain\Foundation\Application(
          $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
      );
      

      更新两个应用程序内核(HTTP 和 CLI)。 在 app/Http/Kernel.php 文件的最顶部,进行以下更改:

      //use Illuminate\Foundation\Http\Kernel as HttpKernel;
      use Gecche\Multidomain\Foundation\Http\Kernel as HttpKernel;
      

      同样在 app/Console/Kernel.php 文件中:

      //use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
      use Gecche\Multidomain\Foundation\Console\Kernel as ConsoleKernel;
      

      使用 config/app.php 文件中 $providers 数组中的扩展的 QueueServiceProvider 覆盖:

      //Illuminate\Queue\QueueServiceProvider::class,
          Gecche\Multidomain\Queue\QueueServiceProvider::class,
      

      发布配置文件。

      php artisan vendor:publish 
      

      用法

      此包添加了三个命令来管理您的应用程序 HTTP 域:

      domain.add 工匠命令 主要命令是 domain:add 命令,该命令将要添加到应用程序的 HTTP 域的名称作为参数。假设我们有两个域,site1.com 和 site2.com,共享相同的代码。

      我们只是这样做:

      php artisan domain:add site1.com 
      

      php artisan domain:add site2.com 
      

      这些命令会创建两个新的环境文件,.env.site1.com 和 .env.site2.com,您可以在其中放置每个站点的特定配置(例如数据库配置、缓存配置和其他配置,如通常所见)在环境文件中)。

      该命令还在 config/domains.php 文件中的 domain 键中添加一个条目。

      此外,还会创建两个新文件夹,即 storage/site1_com/ 和 storage/site2_com/。它们与主存储具有相同的文件夹结构。

      对此存储子结构的自定义必须与 config/domain.php 文件中的值匹配。

      domain.remove artisan 命令 domain:remove 命令通过删除其环境文件从应用程序中删除指定的 HTTP 域。例如:

      php artisan domain:remove site2.com 
      

      添加强制选项将删除域存储文件夹。

      该命令还会从 config/domains.php 文件中的 domain 键中删除相应的条目。

      domain.update_env 工匠命令 domain:update_env 命令传递一个 json 编码的数据数组来更新一个或所有环境文件。这些值将添加到相应 .env 的末尾。

      通过添加域选项更新单个域环境文件。

      当域选项不存在时,该命令会更新所有环境文件,包括标准 .env 文件。

      要更新的域列表保存在 domain.php 配置文件中。

      例如:

      php artisan domain:update_env --domain_values='{"TOM_DRIVER":"TOMMY"}' 会将行 TOM_DRIVER=TOMMY 添加到所有域环境文件中。

      domain.list 工匠命令 domain:list 命令列出当前安装的域,以及它们的 .env 文件和存储路径目录。

      该列表保存在 config/domain.php 配置文件的 domain 键中。

      此列表会在每个 domain:add 和 domain:remove 命令运行时自动更新。

      config:cache artisan 命令 config:cache artisan 命令可以与任何其他 artisan 命令一样与此包一起使用。

      请注意,此命令将为执行该命令的每个域生成一个文件 config.php 文件。 IE。命令

      php artisan config:cache --domain=site2.com 
      

      会生成文件

      config-site2_com.php

      请访问存储库了解更多信息

      【讨论】:

      • 请不要只发布一些工具/包或库作为答案。至少在答案本身中展示how it solves the problem
      • 因为 repo 对包的可用性有很好的解释。
      猜你喜欢
      • 2023-03-29
      • 2020-06-19
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 2020-05-19
      • 2021-03-06
      • 2014-06-06
      • 1970-01-01
      相关资源
      最近更新 更多