想问一个关于在 laravel 里异步执行代码的简单方法

323 天前
 zengguibo

class AdminController extends BaseAdminController {

public function __construct()
{
    
}

public function store(Request $request)
{
    //下面的代码放在后台运行
    UserModel::insert($data);
    //直接返回成功
    $this->success(['desc' => '成功']);
}

} 就是前台调用这个 api 的时候,UserModel::insert($data);这一段放在后台运行,而函数直接返回成功,用队列什么的有点重了,有没有简单点的方法

2101 次点击
所在节点    PHP
20 条回复
ysc3839
323 天前
没办法。PHP 官方至今还是只支持传统的 CGI 模式,即有请求来了就从头执行脚本,直到脚本退出才算请求完成。因此只要后台执行的代码不退出,客户端的请求就不会完成,会一直等着。
zengguibo
323 天前
@ysc3839 感谢你的回复,这个问题我研究了很久也没找到方法,对于这种运行时间太长的 api ,只能用队列的方式了吗
yesC
323 天前
Laravel 的中间件中有个 terminate 方法,可以在把数据响应给客户端后,做一些逻辑处理。
wangxinhui419
323 天前
vjnjc
323 天前
PHP 的本质上是单个 request 走到底,没有线程池
异步依赖于 redis 这种中间件
xiaoxuan6
323 天前
为什么最近老是遇到问这种问题的?既然用 php 了就别纠结这个问题,直接用队列简单方便
https://learnku.com/laravel/t/78187
via
322 天前
我把队列包装了一下,直接把一个函数传递过去就可以了,下面是调用方法:

Async::run(function(){ /* your code here */ });
dedemao
322 天前
dedemao
322 天前
```
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
} else if ($pid) {
//下面的代码放在后台运行
UserModel::insert($data);
pcntl_wait($status);
} else {
//直接返回成功
$this->success(['desc' => '成功']);
}
```
james122333
322 天前
楼上正解 不过不只如此
楼上应该不用讲 框架使用者通常都这样
westoy
322 天前
扔队列, 让消费者去消化

就算原生协程的方案, 这种操作一样是扔队列的

不然被人 C 一下, 这种高耗操作不做任何限制就直接打到上游了
james122333
322 天前
对他们而言 没招可放是很常见的 偏偏混的很好
westoy
322 天前
@james122333

当年 php 官方的态度就是,pcntl 你在 cli 下面用用就好了, 别拿去在 web 下面跑

我还以为十几年没写过 php , 官方转性了, 也没啊

这种常识现在都成冷知识了?

https://www.php.net/manual/en/intro.pcntl.php


"""
Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.
"""

--enable-pcntl Enable pcntl support (CLI/CGI only)
james122333
322 天前
@westoy

不是冷门 但对某些人想破头都不知 他们的知识面被侷限
james122333
322 天前
不管如何他们都还是会解决 只是解法很不漂亮然后不怎么好而已
veike
322 天前
insert 放在后置操作方法里,但是这样要解决什么问题?
demoshengxw
322 天前
我看到有多进程的,但是多进程是不可以宅 fpm 里使用的。但是有一个把 insert 那段代码放在 fastcgi_finish_request 之后执行
thinkingbullet
322 天前
public function store(Request $request)
{
//直接返回成功
$this->success(['desc' => '成功']);
// 此函数会让后面的操作在后台静默运行,仅限于 nginx+php
fastcgi_finish_request();
//下面的代码放在后台运行
UserModel::insert($data);

}
flyqie
322 天前
php 执行异步代码想不做队列还是歇歇吧。

任何语言执行异步请求最稳妥的办法都是搞队列或者任务池。。
guanguans
307 天前
简单一点 afterResponse 就可以了。也可以用 terminate 中间件。原理一样都是 fastcgi_finish_request 。

```php
dispatch(function () {
// UserModel::insert($data);
})->onConnection('sync')->afterResponse();
```

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

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

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

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

© 2021 V2EX