我似乎遇到了一个奇怪的问题。我使用Http facade触发了一个从一个laravel应用到另一个laravel应用的post请求。这两个应用都链接到不同的数据库。当我尝试使用postman触发同一个端点时,它工作正常,但当请求从另一个laravel应用触发时,接收方laravel应用尝试使用发送方应用的数据库设置,但该设置不起作用。我当前使用Windows上的Xampp托管这两个应用,并且软件包是最新版本。有人遇到过类似的问题吗?你能提出解决方案吗?
代码如下所示:发送POST请求的服务(发送方应用程序(1)):
Http::post("http://localhost/second_app/public/api/test", array(
'id' => 1,
);
接收请求的代码(接收器应用程序(2)):
public function test(Request $request)
{
$club = Club::find($request->id);
}
我在日志文件中收到一个错误,指出它正在尝试查找first_app
数据库中的clubs
表,而实际上它应该使用second_app
数据库。我尝试记录配置和请求。在此发布的请求相当大,但我已验证是否正确接收。此日志的代码为:
Log::info("Received Request", ['database' => ['driver' => config('database.default'), 'name' => config('database.connections.'.config('database.default').'.database')]]);
如果请求从Postman发送到second_app或从second_app发送到自身(使用Http facade)
[2021-08-17 03:13:56] local.INFO: Received Request {"database":{"driver":"mysql","name":"second_app"}}
如果使用Http外观将请求从first_app
发送到second_app
[2021-08-17 03:14:01] local.INFO: Received Request {"database":{"driver":"mysql","name":"first_app"}}
[2021-08-17 03:14:01] local.INFO: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'first_app.projects' doesn't exist (SQL: select * from `projects` where `code` = ABC_01 limit 1) {"exception":"[object] (Illuminate\\Database\\QueryException(code: 42S02): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'first_app.projects' doesn't exist (SQL: select * from `projects` where `code` = ABC_01 limit 1) at \\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:692)
应用程序的配置与默认设置相同。. env文件中填充了以下详细信息
#first_app
DB_DATABASE="first_app"
#second_app
DB_DATABASE="second_app"
- UPDATE**我也尝试使用单独的vhosts。
firstapp.test
和secondapp.test
已设置,文档根目录指向公共目录。问题仍然存在,从first_app
发送请求时使用了不正确的配置,但从second_app
或Postman内部发送请求时,该配置工作正常(如前所述)
- UPDATE**我也尝试使用单独的vhosts。
3条答案
按热度按时间ohfgkhjo1#
我尝试在接收方应用中硬编码
database.php
配置值,而不是使用env helper,这解决了问题。看起来env helper在接收方应用中使用发送方应用的环境变量导致了冲突。vq8itlhq2#
我也有同样的问题。
并且我通过使用
php artisan optimize
缓存所有配置来修复它。硬编码数据库配置也可以
vxqlmq5t3#
Laravel使用vlucas/phpdotenv来管理环境变量,phpdotenv从
$_ENV
、$_SERVER
以及可选的php的getenv()
和putenv()
中存储/检索变量。vlucas/phpdotenv不鼓励使用
getenv()
和putenv()
,因为它"不是线程安全的"。这两个php方法将环境变量附加到进程,而不是线程/请求。Windows上的Apache使用mod_php作为php处理程序,在一个进程下运行多个虚拟主机,正如广泛讨论的here。默认情况下,Laravel启用
phpdotenv
库中的putenv
适配器。所以现在的情况是:
1.第一个Laravel站点通过
Env
facade使用putenv()
设置环境变量。1.第一个Laravel站点在同一进程中对作为虚拟主机运行在同一服务器上的第二个Laravel站点进行API调用。
1.第二个站点看到
DB_DATABASE
已经通过读取getenv('DB_DATABASE')
进行了配置,因此读取该值,因为put/getenv()
是进程级的。告诉Laravel禁用
PutenvAdapter
env适配器。将以下行添加到bootstrap/app.php中。Laravel将回退到使用线程安全的$_ SERVER和$_ ENV。要将范围限制为Windows + Apache + mod_php,请使用以下代码。我还没有测试Linux构建的Apache是否会受到putenv虚拟主机交叉污染。
禁用
PutenvAdapter
确实限制了Laravel可以检索环境变量的位置。如果您以不寻常的方式设置环境变量,请确保彻底测试您的应用程序。