用PHP取消cURL请求
我试图用PHP取消一个已经启动的cURL请求。由于我一直在努力寻找一个好的解决方案,我现在被一个unlink函数卡住了,因为cURL正在下载内容,这个函数实际上不起作用用PHP取消cURL请求,php,curl,Php,Curl,我试图用PHP取消一个已经启动的cURL请求。由于我一直在努力寻找一个好的解决方案,我现在被一个unlink函数卡住了,因为cURL正在下载内容,这个函数实际上不起作用 unlink(/foobar/foo.txt): Resource temporarily unavailable in /project/delete.php on line 16 这是我现在遇到的问题: unlink($fileLocation); 由于我没有使用cURL的经验,我不确定如何停止在下载部分执行的cURL请
unlink(/foobar/foo.txt): Resource temporarily unavailable in /project/delete.php on line 16
这是我现在遇到的问题:
unlink($fileLocation);
由于我没有使用cURL的经验,我不确定如何停止在下载部分执行的cURL请求:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_exec($ch);
用例基本上是什么:用户下载一个文件,并且应该有可能取消下载。我如何才能做到这一点?假设您作为守护进程运行下载脚本,您可以使用
CURLOPT_PROGRESSFUNCTION
选项:(否则,您可以通过离开页面或中止xhr来中止请求)
如文件所述:
返回非零值以中止传输。在这种情况下
传输将设置一个CURLE\u ABORTED\u BY\u回调错误
因此,您可以使用一个回调函数,该函数将不断检查数据库值是否设置为true,如果设置为true,则返回1,该函数将中止curl
然后,当用户单击“取消”按钮时,您应该更新数据库并将该值设置为true
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progressCallback');
curl_exec($ch);
if (curl_errno($ch) === CURLE_ABORTED_BY_CALLBACK) {
// Callback aborted
}
function shouldAbortDownload()
{
// Check the database if should abort the download.
}
function progressCallback($ch, $download_size = 0, $downloaded = 0, $upload_size = 0, $uploaded = 0)
{
static $lastCheckTime = 0;
if ((time() - $lastCheckTime) > 4)
if (shouldAbortDownload()) {
return 1;
}
$lastCheckTime = time();
}
}
这个答案是完美的。但它只适用于原始回调函数。
如果在回调函数中插入arg,则无效,例如:
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION,function ($resource, $download_size, $downloaded_size, $upload_size, $uploaded_size) use ($my_arg)
{
progressCallback($resource, $download_size, $downloaded_size, $upload_size, $uploaded_size, $my_arg);
}
);
并处理回调
function progressCallback($resource, $download_size, $downloaded_size, $upload_size, $uploaded_size, $my_arg) {
//some logic
if ($need_to_cancel) {
return 1;
}
}
我非常怀疑这是可能的,因为这是一个同步请求。在什么情况下你想停止下载?@HTMLhell它应该像杀戮一样工作,因为我不关心卷曲的状态。我只想杀死curl,这样我就可以设法删除文件。@D.Brader但是在什么情况下你要这么做?如果你想停止下载/删除该文件,为什么首先要开始下载?@HTMLHELL我提高了PHP执行时间,以允许更长的下载时间。但是,如果用户不想等待那么久,而是想下载一个较短的版本(可能是压缩版或类似的),他可以取消下载。用例是一个用户想要停止他的下载,因为当时每个用户只允许下载一次。谢谢!这对我帮助很大。。。。睡眠(5)可能是个糟糕的主意,每次达到最小值(CURLOPT_BUFFERSIZE,OS_MAX_BUFSIZE)时,它都会停止下载,这可能比睡眠(5)快得多,所以当你下载大文件时,这可能会使下载速度变慢。当你下载小文件时,睡眠(5)会使它暂停5秒,即使文件是在1秒内下载的。更好的方法是
static$lastCheckTime=0;如果((time()-$lastCheckTime)>4&&shouldbortdownload()){return 1;}$lastCheckTime=time()
@htmlhell现在您忘记将$lastCheckTime声明为静态变量,因此代码仍然无法工作,每次都会检查。(因为$lastCheckTime在两次调用之间没有保存,所以每次调用时都会重置为NULL)@HTMLHELL这也是个坏主意,现在它在全局名称空间中放置垃圾并没有好的理由。如果其他代码也决定生成全局$lastCheckTime怎么办?请尝试这样做:-在函数内部,static
关键字是一个存储说明符,这意味着此值只应初始化一次(在本例中为0),并且应在调用之间保留该值。
(同时,令人困惑的是,static
在类/对象中有不同的含义-。-)@hanshenrik我只知道static
在类中做什么,事实上,我对您希望我如何使用它感到困惑。现在我明白了,谢谢:)