2013-07-26 6 views
4

CakePHP 프레임 워크 (v2.x)를 사용하여 PHP 웹 앱을 작성하고 있습니다. 내 견해 중 하나에는 큰 동영상 파일을 타사 API에 업로드하는 형식이 있습니다. 파일이 크기 때문에 업로드하는 데 1-2 분 정도 걸릴 수 있습니다. 그래서 AJAX로 양식을 제출하고 사용자에게 춤추는 하마 (또는 무엇이든)를 보여주기 때문에 바퀴가 여전히 돌아가고 있음을 알게됩니다. 여기에 jquery form plugin 사용하는 스크립트입니다 : 클라이언트에 우리의 API 키를 노출시키지하기 위해AJAX로 PHP 컬 진행 상황을 표시하는 방법

<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> 

가, 내가 사용하는 API에 대한 서버의 실제 POST 요청을 만드는 컨트롤러 액션에 양식을 제출 컬. 이 메소드 (그리고 하나의 콜백)가있다.

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

이 작동하지만 사용자에게 업로드의 실제 진행 상황을 보여줄 수 있다면 훨씬 더 좋을 것이다. 콜백 함수 (***Note B*** 참조)로 이것을 계산하는 방법을 알아 냈습니다 만, 사용자가 대기중인 페이지로 다시 전달하는 방법을 모르겠습니다. jQuery의 uploadProgress을 사용해 보았지만 서버에 업로드하는 파일의 진행 상태를 보여줍니다 ... NOT API 업로드 진행 중. 컬 콜백 (***Note B***)에서 진행 상황을 반향 시키려했지만 API (***Note A***)가 반환 한 json 객체가 복잡하게 뒤얽힌 일련의 숫자가 나온다. 다음과 같은 내용 :

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

어떻게하면 컬 처리 및 후속 API 응답을 캡처 할 수 있습니까?

+0

진행 상황을 확인하기 위해 다른 아약스 전화를 걸 수 있습니까? timeout을 사용하여 완료 될 때까지 진행률을 반복적으로 폴링합니다. –

+0

그건 재미있는 생각이지만, 당신이 생각하는 것을 더 듣고 싶습니다. 예를 들어 두 곳의 아약스 호출을 두 번 생각하고 있습니까? 또는 동일한 컨트롤러에 두 개의 아약스 호출 ... 첫 번째 진행률을 처리하고 두 번째 json 개체를 찾습니다. – emersonthis

+0

다른 컨트롤러에 두 번 호출 할 생각이 있습니다. (저는 Cake TBH에 익숙하지 않습니다) 세션 변수에 진행 상황을 저장하고 진행이 100 %가 될 때까지 폴링하도록 setTimeout을 사용할 수 있습니다. –

답변

0

AJAX를 사용하여 서버의 상태를 확인하고 모든 시간을 전화 할 수 있습니다. 그러나 그것은 서버를 불필요하게 스팸시킬 것이고, 새로운 HTTP 요청이있을 때마다 필요합니다. 웹 소켓을 사용하여 조언 해 드리겠습니다. 서버와 브라우저 사이에 직접 연결을 구축하면 브라우저가 진행될 때 서버가 진행 상황의 업데이트를 직접 보낼 수 있습니다.

+0

웹 소켓은 결국 이런 종류의 해결책이 될 것입니다. 그러나 브라우저 지원은 아직 존재하지 않으며 현재 생산에 들어갈 수있는 것이 필요합니다. – emersonthis

+0

@Emerson 모든 브라우저의 최신 버전은 현재 지원됩니다. [link] (http://caniuse.com/websockets) 물론, 브라우저가 AJAX를 대신 사용하고 지원하지 않으면 폴백 할 수 있습니다. – Hugo

+0

감사합니다. Hugo. 우리가 구축중인 프로젝트는 IE8 +와 나머지 버전의 여러 버전을 지원해야합니다. 후속 질문은 다음과 같습니다. 대체 무엇입니까? – emersonthis

2

당신은 user`s 세션에서 진행 상태를 저장하고 세션에서 정보를 얻을 수 아약스를 사용하여 다음 페이지에 표시 할 수 있습니다

+1

위 질문에 대한 내 의견보기. – emersonthis

0

예, Moshen가 말한대로 :

당신의 진행 상황을 저장할 수 있습니다 user`s 다음 세션 ')는 (session_write_close'

를 다음 세션에서 정보를 얻을 수 Ajax를 사용하는 페이지

에 보여하지만 전화하는 것을 잊지 마세요3210

$nPourcent = round(($total_bytes_up_so_far/$total_bytes_up_expected)*100); 

session_start(); 
$_SESSION['progress'] = $nPourcent; 
session_write_close(); 
관련 문제