php - 请求启动后台 php 脚本
问题描述
我目前正在一个显示大量统计数据的内部网站上工作,由于数据量大,一些页面或 ajax 脚本非常慢。
我正在搜索的是一种通过请求在后台启动这些脚本的方法,然后启动 ajax 请求以了解后台脚本的进度。
有什么办法可以做到这一点?我使用 php7.0 和 apache2 服务器(我无法直接访问 apache 服务器配置,所以如果可能,我会搜索客户端选项)
解决方案
如果有人正在寻找实现这一目标的方法,这是我找到的解决方案:
我在 Ajax 中调用了一个脚本,它分叉自己并将子进程的 PID 保存在数据库中。然后我在子进程中调用 session_write_close() 以允许用户发出新请求,并且父进程退出(不等待子进程结束)。当父亲退出时,用户收到他的请求的答复,子进程继续他的工作。
然后在Ajax中我调用另一个脚本来获取worker的进化,最后我得到结果并在一切完成后杀死子进程。
这是我的工人阶级的代码:
class AsyncWorker
{
private $pid;
private $worker;
private $wMgr;
public function __construct($action, $content, $params = NULL)
{
$this->wMgr = new WorkersManager();
$pid = pcntl_fork(); // Process Fork
if ($pid < 0) {
Ajax::Response(AJX_ERR, "Impossible de fork le processus");
} else if ($pid == 0) { // In the child, we start the job and save the worker properties
sleep(1);
$this->pid = getmypid();
$this->worker = $this->wMgr->fetchBy(array("pid" => $this->pid));
if (!$this->worker) {
$this->worker = $this->wMgr->getEmptyObject();
$this->wMgr->create($this->worker);
}
$this->worker->setPid($this->pid);
$this->worker->setAction($action);
$this->worker->setContent($content);
$this->worker->setPercent(0.00);
$this->worker->setResult("");
$this->wMgr->update($this->worker);
$this->launch($params);
} else { // In the father, we save the pid to DB and answer the request.
$this->worker = $this->wMgr->fetchBy(array("pid" => $this->pid));
if (!$this->worker) {
$this->worker = $this->wMgr->getEmptyObject();
$this->worker->setPid($pid);
$this->wMgr->create($this->worker);
}
Ajax::Response(AJX_OK, "Worker started", $this->worker->getId());
}
}
// Worker job
private function launch($params = NULL)
{
global $form, $_PHPPATH, $url, $session;
session_write_close(); // This is useful to let the user make new requests
ob_start(); // Avoid writing anything
/*
** Some stuff specific to my app (include the worker files, etc..)
*/
$result = ob_get_contents(); // Get the wrote things and save them to DB as result
$this->worker->setResult($result);
$this->worker->setPercent(100);
ob_end_clean();
}
}
这有点棘手,但我别无选择,因为我无法访问服务器插件和库。
推荐阅读
- node.js - 是否可以在不使用框架的情况下在 Node.js 中创建 JWT 身份验证或类似的东西?
- c++ - 对 glewinit、glfwExperimental 等的未定义引用
- c - 为什么 gcc 会改变二进制中函数的顺序?
- javascript - 在 React 中,如何根据子组件计算父组件的宽度?
- node.js - 每次重新启动 npm run dev 时,端口 3000 已在使用中
- resttemplate - 模拟 bean 无法在单元测试中注入依赖关系
- javascript - 用克隆元素替换元素后事件不起作用
- php - 为什么我在升级后未定义身份验证用户提供程序 [eloquent.multiple]
- bash - 数组的值未正确与数字进行比较
- c# - 如何在paint.net 中获取当前活动图像的名称?