重新加载 .env 变量而不重新启动服务器(Laravel 5,共享主机)

Posted

技术标签:

【中文标题】重新加载 .env 变量而不重新启动服务器(Laravel 5,共享主机)【英文标题】:Reloading .env variables without restarting server (Laravel 5, shared hosting) 【发布时间】:2015-12-02 02:04:41 【问题描述】:

我的 Laravel 5 一直运行正常,直到配置好数据库,然后发现这个错误:

SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known

做一些研究,似乎我配置 mysql 访问为时已晚,所以我应该重新启动服务器以获得正确的环境变量。好吧,我正在使用 Dreamhost 的共享服务器,但我做不到。

我应该如何解决这个问题?

谢谢

【问题讨论】:

你不必为了让 Laravel 重新读取它的 .env 文件而重启网络服务器。 Laravel 在每次运行时都会这样做。 @max.lanin 那么如果这不是问题,如果凭据正确,那么问题是什么?我正在运行 php artisan migrate 以便应用迁移 【参考方案1】:

您的配置变量可能已被缓存。验证您的 config/app.php 以及您的 .env 文件,然后尝试

php artisan cache:clear

在命令行上。

【讨论】:

谢谢,但我已经尝试过了。无论如何,如果.env 变量覆盖config/app.php 变量,我为什么要检查这个文件? 他们没有。 config/app.php 文件将它们与 env() 函数一起使用。所有配置文件都可以,真的。所以我会检查config/database.php 以查看对env() 的调用是否使用正确的名称。 让我们看看,如果我的应用程序使用 apache 在本地工作,我应该只调整服务器中 .env 文件中的一些值,对吧?如果config/files 内部没有任何变化,我猜一切都应该正常工作。有什么我错过了该死的【参考方案2】:

config/database.php 中,我将默认数据库连接从mysql 更改为sqlite。我删除了.env 文件(实际上已重命名)并使用touch storage/database.sqlite 创建了sqlite 文件。迁移使用 sqlite。

然后我将config/database.php默认数据库连接切换回mysql并恢复.env文件。迁移使用 mysql。

我猜这没有意义。也许是服务器端的东西。

【讨论】:

即使它解决了您的问题,您也不应该将“hack”标记为答案 - 它会鼓励不良做法【参考方案3】:

如果你在你的服务器上运行了php artisan config:cache,那么你的 Laravel 应用可能会缓存你放在.env 文件中的过时的配置设置。

运行 php artisan config:clear 来解决这个问题。

【讨论】:

运行php artisan config:cache 实际上清除缓存重建它,所以如果你愿意,我建议你不要只使用config:clear继续使用缓存。 但是 如果您在缓存文件之外使用 env() 函数,那么在缓存配置时您将获得 NULL 值。所以请确保只在缓存目录中的文件中使用env()【参考方案4】:

如果有人偶然发现无法重新加载他们的网络服务器(长时间运行的控制台命令,如队列运行器)或需要在请求中重新加载他们的 .env 文件的问题,我找到了一种在 laravel 5 中正确重新加载 .env 变量的方法.

use Dotenv;
use InvalidArgumentException;

try 
    Dotenv::makeMutable();
    Dotenv::load(app()->environmentPath(), app()->environmentFile());
    Dotenv::makeImmutable();
 catch (InvalidArgumentException $e) 
    //

【讨论】:

我的laravel默认好像无法导入Dotenv【参考方案5】:

一个简短的解决方案:

use Dotenv;

with(new Dotenv(app()->environmentPath(), app()->environmentFile()))->overload();
with(new LoadConfiguration())->bootstrap(app());

在我的情况下,我需要在以编程方式更改 .env 后重新建立数据库连接,但它不起作用,如果遇到这个问题,试试这个

app('db')->purge($connection->getName()); 

重新加载 .env 后,这是因为 Laravel App 之前可能已经访问了默认连接,而 \Illuminate\Database\DatabaseManager 需要重新读取配置参数。

【讨论】:

它有效,但我必须使用这两个导入:use Dotenv\Dotenv; use Illuminate\Foundation\Bootstrap\LoadConfiguration; 当涉及到数据库时,DB::reconnect(); 做到了。【参考方案6】:

需要明确的是,根据您的情况,您可以清除 4 种类型的缓存。

php artisan cache:clear

当您希望清除应用程序缓存时,可以在控制台中运行上述语句。它的作用是该语句清除 storage\framework\cache 中的所有缓存。

php artisan route:cache

这会清除您的路由缓存。因此,如果您添加了新路由或更改了路由控制器或操作,您可以使用它重新加载相同的。

php artisan config:cache 

这将清除 env 文件的缓存并重新加载它

php artisan view:clear 

这将清除应用程序的编译视图文件。

对于共享主机

大多数共享主机提供商不提供对系统的 SSH 访问。在这种情况下,您需要创建一个路由并调用以下行:

Route::get('/clear-cache', function() 
    Artisan::call('cache:clear');
    return "All cache cleared";
);

【讨论】:

【参考方案7】:

我知道这是旧的,但对于本地开发人员来说,这就是让事情回到生产 .env 文件的原因:

rm bootstrap/cache/config.php

然后

php artisan config:cache
php artisan config:clear
php artisan cache:clear

【讨论】:

文档明确指出“您通常应该在生产部署例程中运行 php artisan config:cache 命令。该命令不应在本地开发期间运行”【参考方案8】:

这是我能找到的唯一一个与在现有应用实例上重新加载 .envconfig($key) 值相关的问题,但其中许多答案可能应该针对不同的问题。

我为 Laravel 6.x 应用程序工作,同时尝试使用我的 cypress 环境变量制作工匠命令。

对于上下文$this->laravel === app()

    /**
     * Make the application use the cypress environment variables
     *
     * @return void
     */
    protected function enableCypressEnv()
    
        // Get all of the original values from config. We need to do this because
        // rebuilding config will skip packages.
        $old = app(Repository::class)->all();

        // Change the applications env file
        $this->laravel->loadEnvironmentFrom('.env.cypress');

        // Reload the app's environment variables 
        Dotenv::create(
            $this->laravel->environmentPath(),
            $this->laravel->environmentFile(),
            Env::getFactory()
        )->overload();

        // Force config to be rebuitl with new env
        (new LoadConfiguration())->bootstrap($this->laravel);
        
        // Get all of the new values from buidling with new env
        $new = app(Repository::class)->all();

        // Merge the new values over the old distinctly
        $merged = array_merge_recursive_distinct($old, $new);

        // Get the applications configuration instance
        $config = config();

        // Overwrite all of the values in the container in accordance with the merged values
        foreach ($merged as $key => $value) 
            $config->set([$key => $value]);
        
    

感谢上面的答案为我指明了正确的方向,但我将在此处包含我的答案,因为它们都不适合我。

【讨论】:

如果您想知道为什么要这样做,我已经创建了 cypress 通过将配置文件值导出到 json 文件来访问配置文件值的功能。显然,这个文件需要使用正确的 .env 值来构建。由于我经常在本地运行它,我不想经常重命名我的 .env 值,而是可以让命令为我完成。

以上是关于重新加载 .env 变量而不重新启动服务器(Laravel 5,共享主机)的主要内容,如果未能解决你的问题,请参考以下文章

使用 nodemon 或 supervisor 仅重新加载文件而不重新启动所有服务器 - WebStorm

刷新 JSP 变量而不重新加载页面

在sails.js 中更改配置参数而不重新加载服务器

重新启动 gif 动画而不重新加载文件

(Rails)重新加载“lib”文件而无需重新启动服务器......? [复制]

使用 ConfigurationManager.RefreshSection 重新加载配置而不重新启动应用程序