How to show PHP freeze progress using AJAX

I am writing a PHP web application using the CakePHP framework (v2.x). One of my views has a form that uploads a large video file to a third-party API. The files are large, so downloading may take a minute or two. So I submit the form with AJAX and show the user dancing hippo (or something else) so that they know that the wheels are still spinning. Here is a script that uses the jquery form plugin:

<script> var options = { //complete : callback_function..., //error : callback_function..., beforeSend : function() { $("#MediaSubmitForm").hide(); $("#MediaSubmitForm").after('<img class="hula-hippo" src="/img/hippo-hula.gif" />'); }, success : function(data){ $(".hula-hippo").hide(); $("#MediaSubmitForm").after("<h3>Upload complete!</h3>"); console.log(data); }, uploadProgress: function(event, position, total, percentComplete){ console.log(percentComplete); } }; $("#MediaSubmitForm").ajaxForm(options); </script> 

In order not to expose our API key to the client, I submit the form to the controller action, which makes the actual POST request from the API server using curl. Here is this method (and one callback).

 //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*** } 

It works, but better if I can show the user the actual download progress. I figured out how to calculate this using the callback function (see ***Note B*** ), but I'm not sure how to pass it back to the page (where the user is waiting). I tried using jQuery uploadProgress , but it shows the progress of uploading the file to our server ... NOT the upload progress in the API. I tried to repeat the progress from the curl ( ***Note B*** ) callback, but it splashes out a series of numbers that are related to the json object returned by the api ( ***Note A*** ), which I also need. Something like that:

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

How can I capture the curl move and subsequent API response?

+4
source share
3 answers

You can save the execution status in a user session, and then use ajax to get information from the session, and then show it on the page

+2
source

You can check the status on the server using AJAX and let it name any amount of time. But this will save your server from the need, every time it receives a new HTTP request. I advise you to use a web socket. How do you establish a connection directly between the server and the browser so that the server can directly send updates when this happens to the browser.

0
source

Yes, as Moshen says:

You can save the execution status in a user session, and then use ajax to get information from the session, and then show it on the page

but don't forget to call 'session_write_close ()'

 $nPourcent = round(($total_bytes_up_so_far / $total_bytes_up_expected)*100); session_start(); $_SESSION['progress'] = $nPourcent; session_write_close(); 
0
source

Source: https://habr.com/ru/post/1493720/


All Articles