2014-11-14 5 views
0

curl (약 43MB)을 통해 PHP에서 큰 XML 파일을 다운로드 한 다음 해당 파일을 처리하고 데이터 유효성을 검사하고 데이터베이스에 삽입합니다. 문제는로드 밸런서가 5 분 후에 사용자에게 응답을 보내는 것을 중지하고 PHP 스크립트가 약 20 분이 걸리는 것입니다. 두 개의 PHP 스크립트를 동시에 실행하는 방법을 생각했습니다. 하나는 서버에 빈 파일을 만들고, xml 파일을 다운로드하고 처리하며, 마지막에는 빈 파일을 삭제합니다. 다른 PHP 스크립트는 15 초마다 실행되고 빈 파일이 여전히 종료되는지 확인합니다. 이 두 스크립트를 동시에 실행하는 데 문제가 있습니다. 내 코드 :PHP의 비동기식

$(document).ready(function() { 

$(document).on("click", ".clickMe", function() { 
    var download = $.ajax({ 
     async: true, 
     url: "/staff/import.php", 
     type: "post", 
     data: { getFile: true }, 
     dataType: "json", 
     success: function (data) { 
     } 
    }); 

    var serverStatus = true; 
    while (serverStatus === true) { 
     var checkDownload = $.ajax({ 
      async: false, 
      url: "/staff/checkDownload.php", 
      type: "post", 
      dataType: "json", 
      data: { checkDownload: true }, 
      success: function (returndata) { 
       if (returndata === false) { 
        serverStatus = false; 
       } 
      } 
     }); 
    } 

}); 

});

PHP 컬 다운로드 :

<?php 
session_write_close(); 
touch(getcwd() . "downloading"); 
$curl = curl_init(); // 
$post = array("uploadfile"=>"@" . getcwd() . "/tmp.xml"); 
curl_setopt($curl, CURLOPT_URL, "sftp://<host>/bigFile.xml"); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); 
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($curl, CURLOPT_USERAGENT,"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)"); 
curl_setopt($curl, CURLOPT_POST, true); 
curl_setopt($curl, CURLOPT_POSTFIELDS, $post); 
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_SFTP); 
curl_setopt($curl, CURLOPT_USERPWD, "<userName>:<password>"); 
file_put_contents(getcwd() . "/tmp.xml", curl_exec($curl)); 
curl_close($curl); 
unlink(getcwd() . "downloading"); 
// process xml file 
// insert into database 

PHP 체크 다운로드 :

내가 세션을 해제 할 필요가 읽어 병렬로 실행되는 두 개의 PHP 스크립트를 만들기 위해
<?php 
$return = file_exists(getcwd() . "/tmp/downloading"); 
echo json_encode(true); 

[session_write_close();]하지만 여전히 하나 다른 쪽이 끝날 때까지 기다린다. 내 코드 (Javascript 또는 PHP)에 문제가 있거나 다른 방법을 알고 있다면 누구나 내게 빛을 줄 수 있습니까? 감사

+0

나는 이것이 어떻게 실행될 것인가보다는 PHP에 의존한다고 생각한다. 아파치가 내가 아는 한 1까지 1을한다. 내가 틀렸다면 나를 정정하라 ... 더 큰 스크립트는 실행 스택을 "차단"할 것이다. –

+1

서버의 백그라운드에서 작업을 실행하는 중 "대기열"시스템 (어쩌면 진전이 있더라도?). 그런 다음 "queueID"를 다시 보내고 대기열 항목이 완료되면 (매초마다 아약스로 확인) 파일을 반환합니다. – h2ooooooo

+1

그게 내 목표 다. 나는 더 긴 대답을 썼다. @ h2ooooooo에서 뭔가 개선 될 수 있다고 생각하십니까? 내 마음에 무엇이 왔는지 썼습니다. – baao

답변

3

나는 당신이 바로, 당신의 "더 큰 스크립트는"컬 요청입니다 얻을 경우 databasenohup php

기반으로하는 솔루션을 선호하는 것이다. 그래서이 스크립트

touch(getcwd() . "downloading"); 
$curl = curl_init(); // 
$post = array("uploadfile"=>"@" . getcwd() . "/tmp.xml"); 
curl_setopt($curl, CURLOPT_URL, "sftp://<host>/bigFile.xml); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); 
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($curl, CURLOPT_USERAGENT,"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)"); 
curl_setopt($curl, CURLOPT_POST, true); 
curl_setopt($curl, CURLOPT_POSTFIELDS, $post); 
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_SFTP); 
curl_setopt($curl, CURLOPT_USERPWD, "<userName>:<password>"); 
file_put_contents(getcwd() . "/tmp.xml", curl_exec($curl)); 
curl_close($curl); 
unlink(getcwd() . "downloading"); 
// process xml file 
// insert into database 

(!) 참고 :

명령 줄


에서 실행에 삽입 문을 추가 할 때 호출 된 모든 파일에 전체 경로를 설정해야

파일의 시작 부분을 데이터베이스에 삽입하십시오.

INSERT INTO checkrun (started, done) VALUES (NOW(), 0); 
curl_close 후 10

는()의이 /user/curlfile/curlrequest.php 보자, 다른 파일이

UPDATE checkrun set done = 1 WHERE id = (SELECT max(id) FROM checkrun); 

이제 안전과 같은 문장을 추가하고 서버의 아무 곳이나 폴더에 넣어. 지금 당신의 웹 루트에있는 파일로 이동합니다

첫 번째 아약스 호출이 파일은 다음과 같이 exec 문을 포함해야한다 :

exec('nohup php /user/curlfile/curlrequest.php'); 

파일이 현재 실행되고 있고 배경에 설정 수단 나머지 작업에는 영향을 미치지 않습니다. nohup은 일반적으로 당신이 원하지 않는 경우, 당신의 nohup 명령 후

>/dev/null 2>&1 & 

를 추가, 로그 파일을 만듭니다.두 번째 아약스 호출


는 단순히 max(id)에 대한 테이블 checkrun을 확인하는 스크립트를 실행할 수 있으며, 그것은 if done = 1 당신의 컬 요청이 완료 계속하는 if done = 0을 당신은 당신이 원하는대로 할 수 있습니다.

setTimeout(); 

기능을 사용하면 매 15 초마다 또는 원하는 시간에 작업 할 수 있습니다.


참고 :

데이터베이스 검사의이 종류는 당신이 더 많은 내가 아약스 호출을 수행 페이지에서 임의의 문자열을 만드는 것이 경우, 한 번에 하나 개의 컬 요청이있는 경우에만 작동합니다 이 문자열을 파일로 보냅니다. 당신의 컬 파일에

$options = getopt("f:"); 
var_dump($options); 

을 지금 당신은 단순히 내가 didn를 희망 할

WHERE requestId = randomString 

를 확인할 수 있습니다

exec('nohup php /user/curlfile/curlrequest.php -f "randomString"'); 

처럼 간부 명령을 실행 : 당신은 getopt를 사용하여이 작업을 수행 할 수 있습니다 뭔가를 잊지는 마라. 그러나 이것은 가능한 적은 고통으로 일을해야한다.

+0

감사합니다. 아주 좋은 생각이야. 나는 그것을 시도 할 것이고 내가 너와 함께 어떻게 가는지 알려줄 것이다. – ivantxo