PHP 上的异步方法
Asynchronous methods on Php
我正在通过curl(大约43MB)在PHP上下载一个大的XML文件,然后处理该文件,验证数据并插入数据库。问题是负载均衡器在 5 分钟后停止向用户发送响应,PHP 脚本大约需要 20 分钟。我想并行运行两个PHP脚本。一个在服务器上创建一个空文件,下载并处理 xml 文件,最后删除空文件。另一个 PHP 脚本每 15 秒运行一次,并检查空文件是否仍退出。我在并行运行这两个脚本时遇到问题。这是我的代码:
$(document).ready(function() {
$(document).on("click", ".clickMe", function () {
var download = $.ajax({
async: true,
url: "/staff/import.php",
type: "post",
data: { getFile: true },
dataType: "json",
success: function (data) {
}
});
var serverStatus = true;
while (serverStatus === true) {
var checkDownload = $.ajax({
async: false,
url: "/staff/checkDownload.php",
type: "post",
dataType: "json",
data: { checkDownload: true },
success: function (returndata) {
if (returndata === false) {
serverStatus = false;
}
}
});
}
});
});
PHP 卷曲下载:
<?php
session_write_close();
touch(getcwd() . "downloading");
$curl = curl_init(); //
$post = array("uploadfile"=>"@" . getcwd() . "/tmp.xml");
curl_setopt($curl, CURLOPT_URL, "sftp://<host>/bigFile.xml");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_USERAGENT,"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)");
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($curl, CURLOPT_USERPWD, "<userName>:<password>");
file_put_contents(getcwd() . "/tmp.xml", curl_exec($curl));
curl_close($curl);
unlink(getcwd() . "downloading");
// process xml file
// insert into database
PHP检查下载:
<?php
$return = file_exists(getcwd() . "/tmp/downloading");
echo json_encode(true);
为了使两个PHP脚本并行运行,我读到我需要禁用会话[session_write_close();]
但仍然一个等待另一个完成。如果我在代码(Javascript或PHP)上做错了什么,任何人都可以告诉我任何信息,或者知道任何其他方法可以做到这一点?谢谢
我更喜欢基于database
和nohup php
的解决方案
如果我没猜错,你的"更大的脚本"就是 curl 请求。所以拿这个脚本
touch(getcwd() . "downloading");
$curl = curl_init(); //
$post = array("uploadfile"=>"@" . getcwd() . "/tmp.xml");
curl_setopt($curl, CURLOPT_URL, "sftp://<host>/bigFile.xml);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_USERAGENT,"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)");
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($curl, CURLOPT_USERPWD, "<userName>:<password>");
file_put_contents(getcwd() . "/tmp.xml", curl_exec($curl));
curl_close($curl);
unlink(getcwd() . "downloading");
// process xml file
// insert into database
旁注:
在命令行上运行时,您需要设置所有被调用文件的完整路径
并在文件开头添加一个插入语句并将其插入到您的数据库中,例如
INSERT INTO checkrun (started, done) VALUES (NOW(), 0);
在 curl_close() 之后,添加类似
UPDATE checkrun set done = 1 WHERE id = (SELECT max(id) FROM checkrun);
现在将其安全到另一个文件并将其放入服务器上任何位置的文件夹中,让我们采取/user/curlfile/curlrequest.php
.
您的第一个 ajax 调用现在将转到 webroot 中的一个文件,该文件应包含一个 exec
语句,如下所示:
exec('nohup php /user/curlfile/curlrequest.php');
您的文件现在正在运行并设置为后台,这意味着它不会影响您的其余工作(至少更少)。 nohup
通常会创建一个日志文件,如果您不希望这样做,请添加
>/dev/null 2>&1 &
在您的 nohup 命令之后。
使用第二个 ajax 调用,您可以运行一个脚本,该脚本只需检查表检查运行中的max(id)
,if done = 0
它必须继续,if done = 1
curl 请求完成并且您可以做任何您想做的事情。我会与
setTimeout();
每 15 秒或您想要的任何时间检查一次的功能。
注意:
这种数据库检查仅在您一次有一个 curl 请求时才有效,如果您有更多请求,我会在您的页面中创建一个随机字符串来执行 ajax 调用并将此字符串发送到您的文件。您可以使用getopt来执行此操作:
$options = getopt("f:");
var_dump($options);
在你的 curl 文件中并运行你的 exec 命令,如
exec('nohup php /user/curlfile/curlrequest.php -f "randomString"');
现在您可以简单地检查完成
WHERE requestId = randomString
我希望我没有忘记一些事情,但这应该以更少的痛苦来完成这项工作。
- 将其中一个异步方法重写为使用promise的方法
- strongloop script.js run find in before delete方法:如何同步运行异步方法
- QtWebKit中的JavaScript和异步方法
- iframe未执行Javascript方法(PHP)
- Node.js-异步方法调用问题
- Meteor:如何遍历一个数组,这是一个异步方法的结果
- JavaScript中异步方法的优点是什么
- 如何将异步方法返回的值发送到javascript中的另一个异步方法
- 在javascript中链接多个异步方法
- 是否有可能在 JavaScript 中使用异步方法进行迭代
- 如何在 javascript 中同步异步方法
- for 循环中的异步方法
- 在没有jquery的情况下自动滚动到以前位置的最佳方法(PHP和Javascript)
- 方法未按正确的顺序/异步方法调用
- 灯光开关加载所有数据或同步运行异步方法
- PHP 上的异步方法
- 如何确保异步方法已完成
- 如何测试React组件异步方法
- 如何在另一个异步`each`方法(NodeJS)内部进行异步方法调用
- 从JavaScript异步运行PHP