PHP 有没有类似异步的功能?

2017-04-27 18:13:32 +08:00
 cstome

大概情况

我是做前端的,会点 PHP,但不打算花太多时间深入学 PHP (正在学 Python ),所以想问问有没有捷径。

大概需求

最近做个小项目,用 PHP 输出 JSON 并发送邮件,大概逻辑是这样的:

处理 JSON...

返回 JSON...

发邮件(调用 PHPMailer )...

但是这样的话会等待发邮件任务完成在返回 JSON,想知道有什么方法可以先返回(即结束当前脚本),在处理发邮件的任务?

9453 次点击
所在节点    PHP
55 条回复
vus520
2017-04-27 18:16:56 +08:00
你把要发的邮件写到数据库(队列)中,然后有一个独立的程序在后台循环读队列,发邮件就行。

所谓的异步,总是离不开队列。
yxslnmp
2017-04-27 18:22:27 +08:00
swoole...
简单的就用 redis 处理吧
cstome
2017-04-27 18:36:41 +08:00
@vus520 由于使用虚拟主机,所以似乎没法开个进程在后台。。。
xifangczy
2017-04-27 18:39:51 +08:00
1、ajax
2、flush http://php.net/manual/zh/function.flush.php
3、swoole...
lights
2017-04-27 18:47:54 +08:00
首先要有一个队列, 简单的比如 redis, rabbitMQ 其实也很简单
然后主程序将需要发送的邮件内容啊主题啊收件人啊一些信息写到队列里
有另外一个常驻的程序监听这个队列, 并发送邮件

于是就实现了异步啦, 啦啦~~
orderc
2017-04-27 18:48:33 +08:00
php-resque 轻量级的消息队列
bianhua
2017-04-27 18:53:09 +08:00
@cstome 简单的答案是没有。

当然你不在乎把你的处理流程变乱,方法还是有的:
你需要发送 Connection: Close 和 Content-Length 头,设置 set_time_limit、ignore_user_abort,然后用 flush (以及 ob_flush )冲洗缓冲。

这样你的代码在用户浏览器断开之后还能在运行一段时间。

不过这样会导致很多问题,首先运行那段 PHP 代码的进程或线程会阻塞,导致服务器处理效率变低,其次它所占用的内存一直无法被释放。这两条加起来可能会导致 DoS 弱点。

如果是虚拟主机,其实可以想办法写个远程队列服务,或用云邮件服务来解决发送邮件时阻塞的问题(发送 HTTP 请求的延时在绝大多数情况下会比一次 SMTP 会话的延时小一些)。
R18
2017-04-27 18:56:04 +08:00
vus520
2017-04-27 19:44:39 +08:00
@cstome

都有这样的业务需求了,还在用虚拟主机,我服你。
yangyao
2017-04-27 19:46:02 +08:00
pclose(popen("php -f sendmail.php","r"));
sumuu
2017-04-27 20:05:04 +08:00
lygmqkl
2017-04-27 20:07:09 +08:00
借助数据库完成队列,然后 cli 进行发送,如果需要 feedback cli 再更新下数据库记录结果。

ps cli 是多线程,性能不错。可以实现多服务器异歩架构。也可以把这里 cli 换成 py nodejs go
keller
2017-04-27 20:37:00 +08:00
怎么不用 node ?
eoo
2017-04-27 20:45:26 +08:00
前端 干嘛不试试 nodejs ?
mchl
2017-04-27 20:45:45 +08:00
laravel queue
murusu
2017-04-27 20:48:36 +08:00
只能用虚机的话就只能换个想法实现了,你看看这样子行不
PHP 输出 JSON
JSON 存入数据库并返回 JSON 并附带 KEY
浏览器以 KEY 异步调用另一段 PHP 脚本发送邮件
邮件发送成功返回
cxbig
2017-04-27 20:50:36 +08:00
你说的不会是 Host 吧?至少也得换成 VPS
前端干嘛折腾 PHP,用 Node 多好
比方说用 AWS 的解决方案,SQS 保存队列,Lambda 来跟进处理,发邮件可以 用 SNS。
zhs227
2017-04-27 20:52:08 +08:00
虚拟主机的话在请求量不大情况下可以先 ob_flush,然后把线程挂着去发邮件。
访问量大的话就建议至少弄个 vps,不要玩虚拟主机了。
shiny
2017-04-27 20:58:34 +08:00
为啥不用成熟的邮件发送接口,丢给他们去处理。他们有自己的队列。
w7938940
2017-04-27 21:09:20 +08:00
PHP 不能 fork 一个然后在里面执行吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/357776

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX