Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/80.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
如何使用AJAX显示PHP curl进度_Php_Jquery_File Upload_Curl_Cakephp 2.0 - Fatal编程技术网

如何使用AJAX显示PHP curl进度

如何使用AJAX显示PHP curl进度,php,jquery,file-upload,curl,cakephp-2.0,Php,Jquery,File Upload,Curl,Cakephp 2.0,我正在使用该框架(v2.x)编写一个PHP web应用程序。在我的一个视图中,有一个表单可以将一个大的视频文件上传到第三方API。文件很大,因此上传很容易需要一两分钟。因此,我使用AJAX提交表单,并向用户展示一只跳舞的河马(或其他什么),这样他们就知道轮子还在转动。下面是脚本,它使用: 这是可行的,但如果我能向用户展示上传的实际进度,那就更好了。我已经知道了如何使用回调函数计算这个值(请参见***Note B***),但我不确定如何将它传递回页面(用户正在等待)。我尝试使用jQuery的upl

我正在使用该框架(v2.x)编写一个PHP web应用程序。在我的一个视图中,有一个表单可以将一个大的视频文件上传到第三方API。文件很大,因此上传很容易需要一两分钟。因此,我使用AJAX提交表单,并向用户展示一只跳舞的河马(或其他什么),这样他们就知道轮子还在转动。下面是脚本,它使用:

这是可行的,但如果我能向用户展示上传的实际进度,那就更好了。我已经知道了如何使用回调函数计算这个值(请参见
***Note B***
),但我不确定如何将它传递回页面(用户正在等待)。我尝试使用jQuery的
uploadProgress
,但它显示了文件上传到服务器的进度。。。不是上传到API的进度。我尝试回显curl回调(
***Note B***
)的进度,但它吐出了一系列数字,这些数字与api返回的json对象纠缠在一起(
***Note a***
),我也需要它。大概是这样的:

11112222233344444...9898989899999999999999{api:"response mixed in here"}100100100100

如何捕获curl进程和随后的API响应?

您可以使用AJAX检查服务器上的状态,并让它每次调用。但是,这将垃圾邮件您的服务器不必要的,它需要每次一个新的HTTP请求。我建议您使用web套接字。然后直接在服务器和浏览器之间建立连接,这样服务器就可以在浏览器出现问题时直接发送进度更新。

您可以将进度状态存储在用户会话中,然后使用ajax从会话中获取信息,然后在页面上显示它,如Moshen所说:


您可以将进度状态存储在用户会话中,然后使用ajax 从会话中获取信息,然后在第页上显示

但别忘了调用“session\u write\u close()”


你能再打一个ajax电话来检查进度吗?使用timeout反复轮询进度,直到完成。这是一个有趣的想法,但我想听听您的想法。例如,您是否在考虑对两个不同位置的两个ajax调用?或者对同一控制器进行两次ajax调用。。。第一个处理进度,第二个查找json对象。我正在考虑两个对不同控制器的调用(我不熟悉Cake TBH),您可能可以将进度存储在会话变量中,并使用setTimeout进行轮询,直到进度是将进度存储在会话变量中的100%有趣想法。我猜uploadProgress回调只会重复ping,直到完成为止。我可以试一试。我尝试将进度存储在会话变量中。长话短说:这非常棘手,因为PHP会锁定会话文件。因此,同时访问会排队,第二个尝试读取会话的调用必须等到下载完成后(无法访问)。显然,锁定行为是可以操纵的,但我还没有弄清楚。Web套接字最终将成为此类问题的解决方案,但浏览器支持还不存在,我需要一些现在可以投入生产的东西。@Emerson所有浏览器的最新版本,目前都有支持,当然,如果浏览器不支持AJAX,你可以退后一步,改用AJAX。谢谢Hugo。我们正在构建的项目必须支持IE8+以及其他版本。所以我想接下来的问题是:什么是回退?我会让apiUploadCallback函数将进度写入一个文件,其中文件名对应于用户会话。让用户浏览器对你的服务器进行AJAX调用以读取PHP文件,或者直接读取文件,然后让JavaScript来完成其余的工作。。。但是(对于任何想尝试此功能的人),您必须记住一件重要的事情:对于每个用户,进度文件都必须是唯一的。否则多个用户同时会看到来自其他用户的疯狂数据。我这样做的方式是使用当前用户会话id创建/前缀文件名。您还应该记住在完成时删除该文件,这样您就不会得到一百万个进度日志文件。我不知道这种方法在生产中是否稳定。见我在上述问题下的评论。
//uploads a video to a project through the API
public function apiUpload( $tmp_filename, $project_hashed_id ) {
    $api_password = 'xxxxxxxxxx';
    $username = 'api';
    $data = array(
        'api_password'  => $api_password,
        'file'          => '@'.$tmp_filename,
        'project_id'    => $project_hashed_id
        );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_URL, "https://upload.wistia.com" );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);    
    curl_setopt($ch, CURLOPT_NOPROGRESS, FALSE);    
    curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array($this, 'apiUploadCallback'));  
    $result = curl_exec($ch); //***Note A***
    curl_close($ch);
    return( json_decode($result) );

}

//BE CAREFUL... PHP 5.5 Added the cURL resource as the first argument to the CURLOPT_PROGRESSFUNCTION callback 
protected function apiUploadCallback( $total_bytes_down_expected, $bytes_down_so_far, $total_bytes_up_expected, $total_bytes_up_so_far ) {
    if ($total_bytes_up_expected > 0)
        //error_log( round( ($total_bytes_up_so_far / $total_bytes_up_expected)*100) );
        echo ( round( ($total_bytes_up_so_far / $total_bytes_up_expected)*100) ); //***Note B***
}
11112222233344444...9898989899999999999999{api:"response mixed in here"}100100100100
$nPourcent = round(($total_bytes_up_so_far / $total_bytes_up_expected)*100);

session_start();
$_SESSION['progress'] = $nPourcent;
session_write_close();