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

Gab*_*iel 7 php mysql caching angularjs laravel-5.1

我有两个Laravel API,它们都在我的本地开发机器上提供AngularJS应用程序.当Angular页面调用POST给两个API时,我发现了一个奇怪的问题,它似乎使用了错误的数据库名称(它使用的是另一个Laravel实例的数据库).Laravel会抛出一个Table database.table未找到的异常,其中数据库是不正确的数据库.我已经尝试使用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, 
],
Run Code Online (Sandbox Code Playgroud)

存储唯一设置的位置 .env

Den*_*ebe 13

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

php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
php artisan optimize
Run Code Online (Sandbox Code Playgroud)

我不确定哪个命令可以做到,但是Laravel现在可以正确识别/读取.env文件以进行数据库配置.


Sup*_*OVA 9

如果有人像我一样仍然有这个问题。然后,您可以使用以下命令:

php artisan config:cache
Run Code Online (Sandbox Code Playgroud)

在按此处所述设置环境之后。

现在的问题是,每当团队成员更改任何产品的环境文件中的某些内容时,该命令肯定会运行。


Mar*_*ong 7

我遇到了同样的问题,在我的情况下,这是由toddbchttps://github.com/vlucas/phpdotenv/issues/76上报告的问题引起的.

Laravel依赖于它vlucas/phpdotenv,它使用PHP putenv()来添加.env文件中的值,以便应用程序可以访问它们.然而,

putenv()并且getenv()不需要是可重入或线程安全的.这意味着如果两个线程碰巧同时调用它们(在不同的内核上,或者在函数中间的上下文切换中),就会发生不好的事情.

因此,PHP的两个实例(在我的情况下来自不同的应用程序)能够在同时请求期间读取属于彼此的环境变量.

正如vlucas在对问题报告的回复中有用地解释的那样,这是预期的行为,解决方案是在webserver配置文件中定义环境变量.

什么工作对我来说是删除DB_HOST,DB_DATABASE,DB_USERNAME,DB_PASSWORD从我行.env的文件,并添加以下到我的Apache虚拟主机配置块:

SetEnv DB_HOST db_host
SetEnv DB_DATABASE db_name
SetEnv DB_USERNAME db_user
SetEnv DB_PASSWORD db_pass
Run Code Online (Sandbox Code Playgroud)

(更改配置后别忘了重启Apache)

请注意,如果你在你的Web根目录和安装在使用了Apache Alias指令将请求路由到正确的应用程序的子目录附加Laravel应用程序有一个Laravel应用程序,您将需要使用SetEnvIfBOTH套数据库凭据的,就像这样:

# 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
Run Code Online (Sandbox Code Playgroud)

(有关为何不能使用的组合的解释SetEnv,并SetEnvIfhttps://staff.washington.edu/fmf/2013/04/24/using-setenv-and-setenvif-together-in-apache/)

这个解决方案(如果它适用于您)的好处是它只需要在问题出现的环境中实现,即它只影响您的本地开发环境,那么生产服务器上就不需要更改任何内容.


小智 7

老问题,但以防万一其他人发现这种情况发生在他们身上(就像我刚刚发生的那样),我的简单解决方案是更改其中一个项目中 .env 变量的名称:

DB_X_HOST="localhost"
DB_X_DATABASE="other_project"
DB_X_USERNAME="homestead"
DB_X_PASSWORD="secret"
DB_X_PORT="3306"
Run Code Online (Sandbox Code Playgroud)

然后将 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,
    ]
Run Code Online (Sandbox Code Playgroud)

现在你不应该在马克的回应中详细说明交叉污染


Biz*_*oss 6

服务器重启php artisan serve为我解决了同样的问题


小智 0

我有完全一样的问题。一个网页将请求 5 个带有来自 Laravel 的不同数据集的 json 响应,并且大约一半的请求将因“数据库不正确”错误而崩溃,即使当您在自己的浏览器选项卡中重新加载这些确切的请求时,它们也可以正常工作。看起来 Laravel 的 bug 与处理来自 apache 的并发 Web 请求有关。

无论如何,我的解决方法是对 config\database.php 文件中所有连接的主机、数据库、用户名和密码进行硬编码,现在我的 json 请求不再轰炸。然而,必须将密码硬编码到源代码管理中并处理多种环境,这很糟糕——本质上回到了 .env 文件存在之前的黑暗时代。