Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用jquery下载PHP cURL的进度_Javascript_Php_Jquery_Curl - Fatal编程技术网

Javascript 使用jquery下载PHP cURL的进度

Javascript 使用jquery下载PHP cURL的进度,javascript,php,jquery,curl,Javascript,Php,Jquery,Curl,我不知道如何在每次使用php进行更新时推动进度。为了清楚起见,我将写一个例子 jQuery: function uploadMovieDownload(link){ $.post("php/downloadmovie.php", { source:link }, function(json){ console.log(json); }); } uploadMovieDownload(url); PHP(PHP/downloadmovie.PHP): 我的问题是,它在完成后返回进度,而

我不知道如何在每次使用php进行更新时推动进度。为了清楚起见,我将写一个例子

jQuery:

function uploadMovieDownload(link){
    $.post("php/downloadmovie.php", { source:link }, function(json){ console.log(json); });
}

uploadMovieDownload(url);
PHP(PHP/downloadmovie.PHP):

我的问题是,它在完成后返回进度,而不是在下载时推送进度。如果您有任何建议,请提前感谢。

不要使用ob_flush(),只使用flush()。 (删除所有ob_uu功能)。 另外,考虑修改缓冲区大小:

curl_setopt($ch, CURLOPT_BUFFERSIZE, 16000);

尝试大小。

完成所有脚本后,PHP将显示结果。这就是你刚刚完成进度的原因

您可以在后台执行curl下载,并将进度写入会话、数据库、会话或内存,如redis、memchche。然后在客户端,每隔很短的时间读取一次进程


您也可以使用Iframe来实现这一点。

使用该方法,您将遇到各种缓存问题,php输出缓冲吗?你会有问题的。您是否在web服务器后面,比如nginx/apache/lighthttp/anything?你会有问题的。浏览器是否正在缓存输出?(所有主流浏览器都有),你会遇到问题

我建议一个没有这些问题的替代方案:使用$_会话存储下载百分比,并使用XMLHttpRequests查询百分比(实际上通过WebSocket查询百分比是最佳的、滞后的、使用较少的bw等,但实现起来要困难得多)

下载电影.php

<?php 
require_once(dirname(__FILE__)."/functions.php");


$url = $_POST['source'];
$headers = getHeaders($url);
$url = $headers['url'];
//after validation of input
session_start();
$_SESSION['download_percentage']=0.0;//initialize it
session_write_close();
fastcgi_finish_request();//or if you're not using fcgi, some equivalent..

$path = dirname(__FILE__)."/temp/test.mp4";

$fp = fopen ($path, 'w+');
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
curl_setopt( $ch, CURLOPT_PROGRESSFUNCTION, 'progress' );
curl_setopt( $ch, CURLOPT_NOPROGRESS, false );
curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 100 );
curl_setopt( $ch, CURLOPT_FILE, $fp );
curl_exec( $ch );
curl_close( $ch );
fclose( $fp );


function progress($resource,$download_size, $downloaded, $upload_size, $uploaded){
    $percentage=$download_size==0? 0.0 : (($downloaded/$download_size)*100);
    session_start();
    $_SESSION['download_percentage']=$percentage;
    session_write_close();
}
引用自
echo”“;
回声“加载…”;
ob_flush();
冲洗();
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,”http://stackoverflow.com");
//curl_setopt($ch,CURLOPT_BUFFERSIZE,128);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_PROGRESSFUNCTION,'progress');
curl_setopt($ch,CURLOPT_NOPROGRESS,false);//需要使功能工作取得进展
curl_setopt($ch,CURLOPT_头,0);
curl_setopt($ch,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT');
$html=curl\u exec($ch);
卷曲关闭($ch);
功能进度($resource,$download\u size,$download,$upload\u size,$upload)
{
如果($download_size>0)
echo$download/$download_size*100;
ob_flush();
冲洗();
睡眠(1);//只是为了看看效果
}
回应“完成”;
ob_flush();
冲洗();
?>

您好,您有这个问题的解决方案吗……一些想法:1。负载平衡器可能会无意中保存渐进响应。2.您需要立即发送一定数量的字节,以使某些浏览器正常工作。3.您需要返回HTML,并将数据有条理地包装在
标记中,以使用这样一种简单的COMET方法。4.我会考虑使用一个临时文件来重新存储百分比,并用另一个简单的脚本来从文件中获取这个值,绕过上面的脚本。5.“SSE”,又名
EventSource
是跨浏览器的,很容易在PHP中实现,以取代#4中的ping…我认为这是最好的解决方案,但不要忘记在每次更新后都需要使用
session\u write\u close
,然后在更新之前再次使用
session\u start
,否则,Ajax请求将被锁定,直到会话关闭为止,因为它将被锁定并阻止使用同一会话的后续请求。为什么要在if中包装会话\u start?它做的第一件事就是调用它?如果它知道加载它,请从cookie中检查会话\u id。@drew010哇。我不知道,谢谢!我会在一个小时内更新代码sec@MartinBarker我不知道在调用实际的php文件之前运行的是什么,但是一些站点在
auto\u prepend\u file
php.ini指令或类似的x.x中开始会话。在这种情况下,调用session\u begin()而不检查它是否已经开始,将导致错误(我相信是E\u注意吗?)-刚刚检查过,是的:
注意:会话已经启动-忽略第4行C:\WTServer\WWW\sesstest\2.php中的session\u start()
如果我尝试在没有会话启动的情况下使用$\u session,即使会话已经在其中,但对我不起作用,这会很奇怪。。。
<?php 
require_once(dirname(__FILE__)."/functions.php");


$url = $_POST['source'];
$headers = getHeaders($url);
$url = $headers['url'];
//after validation of input
session_start();
$_SESSION['download_percentage']=0.0;//initialize it
session_write_close();
fastcgi_finish_request();//or if you're not using fcgi, some equivalent..

$path = dirname(__FILE__)."/temp/test.mp4";

$fp = fopen ($path, 'w+');
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
curl_setopt( $ch, CURLOPT_PROGRESSFUNCTION, 'progress' );
curl_setopt( $ch, CURLOPT_NOPROGRESS, false );
curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 100 );
curl_setopt( $ch, CURLOPT_FILE, $fp );
curl_exec( $ch );
curl_close( $ch );
fclose( $fp );


function progress($resource,$download_size, $downloaded, $upload_size, $uploaded){
    $percentage=$download_size==0? 0.0 : (($downloaded/$download_size)*100);
    session_start();
    $_SESSION['download_percentage']=$percentage;
    session_write_close();
}
<?php 
if(""===session_id()){
session_start();
}
echo $_SESSION['download_percentage']??'?';
(function checkProgress() {
    "use strict";
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "getProgress.xhr.php");
    xhr.addEventListener("readystatechange", function(ev) {
        var xhr = ev.target;
        if (xhr.readyState !== 4) {
            return;
        }
        console.log(xhr.responseText + " percent downloaded!");
        if (xhr.responseText === "100") {
            return; /*stop checking for progress when its finished*/
        }
        setTimeout(checkProgress, 1000); //<<check for progress every 1 second

    });
    xhr.send();
})();
echo "<pre>";
echo "Loading ...";

ob_flush();
flush();

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://stackoverflow.com");
//curl_setopt($ch, CURLOPT_BUFFERSIZE,128);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress');
curl_setopt($ch, CURLOPT_NOPROGRESS, false); // needed to make progress function work
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
$html = curl_exec($ch);
curl_close($ch);


function progress($resource,$download_size, $downloaded, $upload_size, $uploaded)
{
    if($download_size > 0)
         echo $downloaded / $download_size  * 100;
    ob_flush();
    flush();
    sleep(1); // just to see effect
}

echo "Done";
ob_flush();
flush();

?>