Php 奇怪的Laravel 5缓存使用了错误的数据库名称
我有两个LaravelAPI,它们在本地开发机器上为AngularJS应用程序提供服务。当Angular页面调用两个API的POST时,我遇到了一个奇怪的问题,它似乎使用了错误的数据库名称(它使用的是另一个Laravel实例的数据库)。Laravel抛出一个异常,表示Php 奇怪的Laravel 5缓存使用了错误的数据库名称,php,mysql,angularjs,caching,laravel-5.1,Php,Mysql,Angularjs,Caching,Laravel 5.1,我有两个LaravelAPI,它们在本地开发机器上为AngularJS应用程序提供服务。当Angular页面调用两个API的POST时,我遇到了一个奇怪的问题,它似乎使用了错误的数据库名称(它使用的是另一个Laravel实例的数据库)。Laravel抛出一个异常,表示表数据库。未找到表,其中数据库是不正确的数据库。我尝试过使用Postman调用每个API,效果很好,我确信在这两个项目中都没有提到其他数据库 在我看来,这似乎是一个缓存问题,由于某种原因,.env文件可能被缓存并在两个Laravel
表数据库。未找到表,其中数据库是不正确的数据库。我尝试过使用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
中时,我遇到了完全相同的问题。一个网页将从laravel请求5个带有不同数据集的json响应,其中大约一半的请求会出现“不正确的数据库”错误,即使当您在自己的浏览器选项卡中重新加载这些确切的请求时,它们仍能正常工作。似乎是一个Laravel bug,与处理来自apache的同步web请求有关
无论如何,我的解决方法是在config\database.php文件中硬编码所有连接的主机、数据库、用户名和密码,现在我的json请求不再爆炸。然而,必须将密码硬编码到源代码管理中并处理多个环境,这很糟糕——基本上可以追溯到.env文件存在之前的黑暗时代。我也遇到过同样的问题,在我的案例中,这是由toddbc报告的问题引起的
Laravel依赖于vlucas/phpdotenv
,它使用PHP的putenv()
从.env
文件中添加值,以便应用程序可以访问这些值。但是,
putenv()
和getenv()
不需要是可重入的或线程安全的。这意味着,如果两个线程同时调用它们(在不同的内核上,或者从函数中间的上下文切换)调用,那么坏事就可能发生。
因此,两个PHP实例(在我的例子中来自不同的应用程序)能够在Concurrent请求期间读取属于彼此的环境变量
正如vlucas在他对问题报告的回复中有益地解释的那样,这是预期的行为,解决方案是在Web服务器配置文件中定义环境变量
对我来说,有效的方法是从我的.env
文件中删除DB\u主机
,DB\u数据库
,DB\u用户名
,DB\u密码
行,并将以下内容添加到我的Apache vhost配置块中:
SetEnv DB_HOST db_host
SetEnv DB_DATABASE db_name
SetEnv DB_USERNAME db_user
SetEnv DB_PASSWORD db_pass
(不要忘记在更改配置后重新启动Apache)
请注意,如果您的web根目录中有一个Laravel应用程序,并且在使用Apache Alias指令将请求路由到正确的应用程序的子目录中安装了另一个Laravel应用程序,则需要对两组数据库凭据使用setenif
,如下所示:
# 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
(有关无法组合使用SetEnv
和setenif
的原因,请参阅)
这个解决方案的好处是(如果它对您有效的话)只需要在出现问题的环境中实现,即如果它只影响您的本地开发环境,然后,不需要在生产服务器上更改任何内容。对我来说,有效的方法是通过运行以下命令来清除一系列Laravel设置:
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
php artisan optimize
我不确定是哪个命令做的,但Laravel现在可以正确识别/读取我数据库配置的.env文件。老问题,但为了防止其他人发现这种情况发生在他们身上(就像我刚刚遇到的一样),我的简单解决方案是更改其中一个项目中.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,
]
现在,您不应该在Mark的回复中详细说明交叉污染问题如果有人像我一样仍然存在此问题,则使用php artisan serve重新启动服务器
已为我修复了相同的问题。然后可以使用以下命令:
php artisan config:cache
如前所述设置环境后
现在的问题是,每当团队成员在任何产品的环境文件中更改某些内容时,都应该运行此命令。这对我来说很有效:
php artisan config:cache
您只需键入以下命令:
php artisan config:cache
对我来说,不需要额外操作,只需清除缓存并重新启动Apache2即可:
php artisan config:cache
sudo /etc/init.d/apache2 restart
我还没有解决这个问题,但作为一种临时解决方法,我现在只是基于env('app_env')的值在app/config/database.php中定义数据库凭据,而不是将这些凭据存储在.env文件中。请停止服务器并再次运行(php artisan serve)谢谢-尝试了第一个(config:clear),它成功了。我相信剩下的可能没有必要。我的config/database.php中有一个die(),它没有被调用——在我执行“php artisan config:clear”之后,它被调用(简而言之,这对我来说很有效)是最好的答案。更改变量名对我很有效。我同意,最佳解决方案Hi Toufic!你能解释一下这个解决方案是做什么的,为什么它能解决这个问题,甚至可以提供一些外部链接来获取更多信息吗