奇怪的Laravel 5缓存使用错误的数据库名称

12

我有两个 Laravel API,在本地开发机上为 AngularJS 应用提供服务。当 Angular 页面调用这两个 API 进行 POST 请求时,我遇到了一个奇怪的问题:它似乎使用了错误的数据库名称(它正在使用另一个 Laravel 实例的数据库)。Laravel 抛出一个异常,说找不到 表 database.table,其中 database 是错误的数据库名称。我已经尝试使用 Postman 调用了每个 API,一切都正常工作,并且我确定在任何项目中都没有提到其他数据库。

对我来说,这似乎是一个缓存问题,可能是 .env 文件在两个 Laravel 服务器之间被缓存和共享的原因。这两个 Laravel 应用都托管在 Apache 上。我尝试调用 php artisan config:clear,并设置了适当的头文件在 .htaccess 文件中,以尝试防止任何缓存,但这两者都没有起作用。我还尝试了多个浏览器,清除了缓存,但仍然出现相同的错误。

我希望能够使用 .env 文件,以便在开发服务器上拥有唯一的配置,所以我不想在 config/database.php 中硬编码数据库凭据。有什么想法可能是问题的原因吗?

两个 database.php 文件看起来像:

'mysql' => [
'driver'    => 'mysql',
'host'      => env('DB_HOST'),
'database'  => env('DB_DATABASE'),
'username'  => env('DB_USERNAME'),
'password'  => env('DB_PASSWORD'),
'charset'   => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix'    => '',
'strict'    => false, 
],

存储唯一设置的位置在.env中。


我还没有解决这个问题,但是作为一个临时的解决方法,我现在根据env('APP_ENV')的值,在app/config/database.php中定义数据库凭据,而不是将它们存储在.env文件中。 - Gabriel
停止服务器并重新运行(php artisan serve) - Mert Metin
我也遇到了同样的问题。我找到了解决方法:运行 php artisan optimize 命令,该命令将清除配置、路由和文件缓存,并创建新的缓存。每次编辑路由或 .env 文件后都需要运行此命令。 - Hemant Prajapat
11个回答

22

对我有用的是通过运行以下命令来清除一些Laravel设置:

php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
php artisan optimize

我不确定是哪条命令做到了这一点,但现在Laravel可以正确地识别/读取我的数据库配置文件.env了。


谢谢 - 我尝试了第一个(config:clear)并且它起作用了。我相信其余的可能是不必要的。 - Zachary Schuessler
我的config/database.php文件中有一个die()函数,但它没有被调用。在我执行了“php artisan config:clear”命令之后,它才被调用了(简而言之,这对我起作用了)。 - NULL pointer

19
如果仍然存在此问题,就像我所遇到的一样。那么您可以使用以下命令:

如果仍然有这个问题,就像我的情况一样。那么您可以使用以下命令:

php artisan config:cache

在按照这里提到的方式设置环境后,现在的问题是,每当团队成员更改任何产品的环境文件时,此命令都应该运行。


这行代码救了我的一天,谢谢。 - Mohammed H. Hannoush

7
我遇到了同样的问题,而在我的情况下,导致这个问题的原因是由 toddbchttps://github.com/vlucas/phpdotenv/issues/76上报告的问题。
Laravel 依赖于 vlucas/phpdotenv,它使用 PHP 的 putenv() 将来自 .env 文件的值添加到应用程序中以便访问。然而,

putenv()getenv() 不需要是可重入或线程安全的。这意味着,如果两个线程同时调用它们(可以是在不同的核心上,也可以是在函数执行过程中进行的上下文切换),会发生糟糕的事情。

因此,在并发请求期间,我的情况下两个 PHP 实例(来自不同的应用程序)能够读取彼此属于的环境变量。
正如vlucas在回复问题报告时所指出的那样,这是预期行为,解决方法是在您的 Web 服务器配置文件中定义您的环境变量。
对我有效的方法是从我的 .env 文件中删除 DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD 行,并在我的 Apache vhost 配置块中添加以下内容:
SetEnv DB_HOST db_host
SetEnv DB_DATABASE db_name
SetEnv DB_USERNAME db_user
SetEnv DB_PASSWORD db_pass

在更改配置后,不要忘记重新启动Apache。

请注意,如果您的网站根目录中有一个Laravel应用程序,并且还安装有一个额外的Laravel应用程序,该应用程序使用Apache别名指令将请求路由到正确的应用程序,则需要同时对两组数据库凭据使用SetEnvIf,如下所示:

# Laravel app 1 in web root
SetEnvIf Host ".*" DB_HOST=db1_host
SetEnvIf Host ".*" DB_DATABASE=db1_name
SetEnvIf Host ".*" DB_USERNAME=db1_user
SetEnvIf Host ".*" DB_PASSWORD=db1_pass

# Laravel app 2 in subdirectory "/subdir"
SetEnvIf Request_URI ^/subdir DB_HOST=db2_host
SetEnvIf Request_URI ^/subdir DB_DATABASE=db2_name
SetEnvIf Request_URI ^/subdir DB_USERNAME=db2_user
SetEnvIf Request_URI ^/subdir DB_PASSWORD=db2_pass

(关于为什么不能同时使用 SetEnvSetEnvIf 的解释,请参见https://staff.washington.edu/fmf/2013/04/24/using-setenv-and-setenvif-together-in-apache/
这种解决方案的好处在于(如果适用于您),它只需要在出现问题的环境中实施,例如,如果它只影响您的本地开发环境,则不需要在生产服务器上进行任何更改。

看起来PHP FPM也使用了一些缓存。echo "" | sudo -S service php7.3-fpm reload解决了我的问题(将其替换为您的PHP版本号)。 - A A Karim

7

虽然这是一个老问题,但如果其他人(就像我一样)发现了这种情况,我的简单解决方法是更改其中一个项目中的.env变量的名称:

DB_X_HOST="localhost"
DB_X_DATABASE="other_project"
DB_X_USERNAME="homestead"
DB_X_PASSWORD="secret"
DB_X_PORT="3306"

然后您需要更改config\database.php中的变量,使其读取:

'mysql' => [
        'driver' => 'mysql',
        'host' => env('DB_X_HOST', '127.0.0.1'),
        'port' => env('DB_X_PORT', '3306'),
        'database' => env('DB_X_DATABASE', 'forge'),
        'username' => env('DB_X_USERNAME', 'forge'),
        'password' => env('DB_X_PASSWORD', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ]

现在你不应该有马克回答中提到的交叉污染问题了。


1
最佳答案。更改变量名称对我有用。 - mutiemule
我同意,这是最佳解决方案。 - rockstardev

6

对我而言,使用 php artisan serve 重新启动服务器解决了同样的问题。


1

你需要做的就是输入这个命令:

php artisan config:cache

0
这对我有用:
php artisan config:cache

嗨Toufic!你能否解释一下这个解决方案是做什么的,为什么它可以解决这个问题,甚至可以提供一些外部链接以获取更多关于你的解决方案的信息吗?谢谢 :) - Ullaakut

0

我有完全相同的问题。一个网页将从laravel请求5个不同数据集的json响应,其中大约一半的请求会因为“不正确的数据库”错误而失败,即使当您在其自己的浏览器选项卡中重新加载这些确切的请求时,它们也能正常工作。似乎是Laravel处理来自Apache的同时Web请求的一个bug。

无论如何,我的解决方法是在我的config \ database.php文件中为所有连接硬编码主机,数据库,用户名和密码,现在我的json请求不再失败了。然而,将密码硬编码到源代码控制中并处理多个环境非常麻烦 - 实际上回到.env文件存在之前的黑暗时代。


0

对于我而言,在没有进行其他操作的情况下,只需要清除缓存并重新启动Apache2即可:

php artisan config:cache
sudo /etc/init.d/apache2 restart

0

我也遇到了一些随机的Unknown database 'dbname'错误,记录的名称与.env文件中实际名称不匹配。

对我来说,没有任何答案有效,但重新启动整个服务器确实有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接