PHP fiber 一直等到完成,我不想等

PHP fiber waits until finish which i don't want to wait

我想使用Fiber (PHP 8.1) 创建一个线程来发送电子邮件(电子邮件发送需要 10 秒,所以我决定使用线程)。这是我的代码

<?php
$fiber = new Fiber(function () {
    send_email();
});
$fiber->start();

exit(json_encode(['response' => 1]));

send_email() 的结果并不重要,但启动纤程后,纤程会等待 send_email() 完成,然后 exit(json_encode(['response' => 1])); 发生 !!!!我希望它立即退出,但也要发送电子邮件!!! 有什么问题?

根据 https://www.php.net/manual/en/language.fibers.php 的说法,Fiber 是可中断的,但没有提到它是完全异步或多线程的——它不允许主函数继续自动执行……根据我对它的阅读仅当您暂停 Fiber 时才会发生 - 实际上这就是您在代码中报告的体验。

PHP 是 single-threaded,也没有任何合适的 task-based 异步编程模型(不幸的是,与其他 server-side 相比,这是现在的主要弱点nodeJS 或 C# 等语言)。

https://php.watch/versions/8.1/fibers 也说

It is important the concurrent execution does not mean simultaneous execution. The Fiber and the main execution flow does not happen at the same time. It is up to the main execution flow to start a Fiber, and when it starts, the Fiber is executed exclusively.

Fiber by itself does not allow simultaneous execution of multiple Fibers or the main thread and a Fiber.

...所以我认为您可能误解了此功能及其功能 - 它无法帮助您满足您的要求。

AFAIK PHP 不可能做你正在尝试的事情。更好的解决方案可能是将电子邮件发送到一个单独的进程 - 例如cron 触发的后台任务。这是一个相当典型的模式:PHP 收到一个要求它发送电子邮件的请求。它将请求记录在数据库 table 中,然后退出。后台任务按计划执行,从数据库 table 中提取任何未完成的任务并运行它们,然后更新 table 以表明它们已完成。这样一来,后台任务是否需要更长的时间并没有多大关系,因为它不会减慢网站或最终用户的速度。