在php中,执行异步任务是一种很常见的需求,如批量发邮箱,短信等等执行耗时任务时,需要程序异步执行,给用户带来好的体验。
在php异步执行代码就很尬尴,不像java 可以创建多线程,在php中也可以用pcntl_fork()实现创建子进程,来实现异步,但这样可能会产生很多僵尸进程。其他的方式借助框架实现,如优秀的swoole框架,本文介绍无需安装如何框架扩展,php自带的方式处理
下面直接上代码,我用的thinkphp6
在extend下创建一个util类,代码如下
<?php
namespace util;
class AsyncHook
{
private static $hook_list = array();
private static $hooked = false;

public static function hook($callback, $params = [])
{
self::$hook_list[] = array('callback' => $callback, 'params' => $params);
if (self::$hooked == false) {
self::$hooked = true;
register_shutdown_function(array(__CLASS__, '__run'));
}
}

public static function __run()
{
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
}
if (empty(self::$hook_list)) {
return;
}
foreach (self::$hook_list as $hook) {
$callback = $hook['callback'];
$params = $hook['params'];
call_user_func_array($callback, $params);
}
}
}
调用方式
$namespaceClass = "app\\api\\task\\Test";
$classObj = app($namespaceClass);
\util\AsyncHook:hook([$classObj,"index"],['name'=>1]);
$this->success("");
执行结果,会先$this->success()返回数据,后执行hook中的Test index方法。很简单。