用PHP取消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请

我试图用PHP取消一个已经启动的cURL请求。由于我一直在努力寻找一个好的解决方案,我现在被一个unlink函数卡住了,因为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
在类中做什么,事实上,我对您希望我如何使用它感到困惑。现在我明白了,谢谢:)