2012-05-14 5 views
17

함수를 시간 종료하는 방법이 있습니까? 나는 10 분 동안 일을해야한다. 작업은 여기에 루프를 포함하는 예입니다PHP의 함수에서 시간 초과

<?php 
foreach($arr as $key => $value){ 
    some_function($key, $value); //This function does SSH and SFTP stuff 
} 
?> 

$의 편곡이 15 개 요소 때로는 1 개 이상 분 정도 걸릴 수 있습니다 some_function()를 가지고있다. 사실 5 분 동안 매달렸다.

함수 호출을 시간 초과하고 $ arr의 다음 요소로 넘어갈 수있는 방법이 있습니까?

감사합니다.

+0

몇 가지 질문 : 그것은이다 그 10 분을 제한하는거야? ssh/sftp 작업이 실행되는지 여부는 중요하지 않습니까? 어떤 종류의 대기열을 사용하여이 제한을 해결할 수 있습니까? – aurora

+0

10 분마다 실행되는 crontab 스크립트입니다. 서버 상태를 확인하고 데이터베이스를 업데이트합니다. 내가 1 분 안에 응답을 얻지 못한다면, 서버를 느리게 설정하는 중입니다 ... – Mo3z

답변

13

구현에 따라 다릅니다. PHP 함수의 99 %가 차단되고 있습니다. 의미 처리는 현재 함수가 완료 될 때까지 계속되지 않습니다. 그러나 함수에 루프가 포함되어 있으면 특정 조건이 충족 된 후에 루프를 인터럽트하기 위해 자체 코드를 추가 할 수 있습니다. 이 같은

뭔가 :

foreach ($array as $value) { 
    perform_task($value); 
} 

function perform_task($value) { 
    $start_time = time(); 

    while(true) { 
    if ((time() - $start_time) > 300) { 
     return false; // timeout, function took longer than 300 seconds 
    } 
    // Other processing 
    } 
} 

처리를 방해하는 것은 불가능하다 또 다른 예 :

foreach ($array as $value) { 
    perform_task($value); 
} 

function perform_task($value) { 
    // preg_replace is a blocking function 
    // There's no way to break out of it after a certain amount of time. 
    return preg_replace('/pattern/', 'replace', $value); 
} 
+0

감사합니다 마이크하지만 some_function 또는 perform_task는 핵심 기능이며 핵심 방법을 수정하지 않으려 고합니다. – Mo3z

+1

경로 지정 : 새 스크립트 example.php를 만들고 some_function에서 해당 스크립트를 호출하고 some_function의 set_time_limit ... 논리를 정의하면 example.php에서 실행됩니다. – Mo3z

+0

동일한 문제, 동일한 기법. –

8

PHP는 단일 스레드입니다 ... 당신이 다른 프로세스를 포크로 당신의 OS의 기능을 사용해야합니다 .

이 작업을 수행하는 방법을 알고있는 유일한 방법은 exec 명령을 사용하여 다른 전체 프로세스를 포크하는 것입니다. 원하는 스크립트를 별도의 스크립트에 넣고 스크립트에서 exec를 호출 한 다음 10 분간 바로 잠자기하십시오. 10 분이 지나면 프로세스가 계속 실행됩니다. (명령은 명령을 통해 새로운 PHP 코드를 백그라운드로 실행하고 명령 행을 통해 가져 와서 exec 명령에서 리턴시킴으로써 PID를 가져야한다).

+0

모든 PHP가 스레드가 아닌 경우 –

4

루프를 시작하기 전에 time()을 기억하는 변수를 설정하십시오. 각 반복의 끝에서 현재 time()이 60 초 이상 더 큰지 확인하십시오. 그렇다면 break. 예 :

<?php 
$startTime=time(); 
foreach($arr as $key => $value){ 
    some_function($key, $value); //This function does SSH and SFTP stuff 
    if (time()-$startTime>60) break; //change 60 to the max time, in seconds. 
} 
?> 
+0

David 님의 답변입니다. for 루프를 깰 필요가 없습니다. 1 분 이상 걸리면 some_function을 해제해야합니다. – Mo3z

1

set_time_limit을 살펴보십시오. 이제 함수 자체는 실행 시간을 고려하기 때문에 실제로 원하지 않습니다. 실제 생활에서 5 초가 여전히 0.2 초만 실행될 수 있음을 의미합니다. 그러나 링크를 보는 이유는 주석 때문입니다. 사용자가 게시 한 몇 가지 솔루션이 있습니다.

5

'컬'을 사용하여 구현할 수 있습니다. Curl은 - PHP에서 - 주로 HTTP/FTP 작업을하는 데 사용되지만 ssh/sftp를 포함한 더 많은 프로토콜을 지원합니다. 커밋을 사용하여 ssh/sftp 관련 작업을 한 번도 한 적이 없으므로 추가 조언을 드릴 수는 없지만 stackoverflow 또는 다른 곳에서 추가 정보를 찾을 수 있어야합니다.

요청에 대한 시간 초과를 구성하는 데 사용할 수있는 "CURLOPT_TIMEOUT"옵션이 있습니다 ("CURLOPT_CONNECTTIMEOUT"옵션도 있음). 밀리 초 단위로 시간 제한을 지정할 수도 있습니다 (CURLOPT_TIMEOUT_MS/CURLOPT_CONNECTTIMEOUT_MS).

어쨌든 : cronjob에 대해서는 스크립트가 시작될 때 "lock-file"을 쓰는 것이 좋습니다. 스크립트가 실행될 때 작성하고 실행이 끝나면 제거합니다. 스크립트 내에서이 잠금 파일을 검사 할 수 있으므로 cron이 스크립트 을 실행하기 전에 마지막 실행이 끝나면 더 이상 스크립트를 종료 할 수 있습니다. 이렇게하면 스크립트가 여러 번 병렬로 실행되지 않습니다.

당신은 역시 CURL 옵션에 대한 자세한 내용을 찾아 PHP 문서 자체 컬 수 있습니다

당신은 할 필요가 있는지, 그 설치된 libcurl에와/또는 curl은 SSH/SFTP를 지원합니다 :

도움 등

희망

  • SFTP from within PHP
  • SFTP from PHP - undefined constant CURLOPT_PROTOCOLS and CURLPROTO_SFTP? ...

    7

    은 당신이 원하는 것은 제한 시간에 SIGALRM 신호를 트리거 할 pcntl_alarm 기능을 사용하는 것입니다. 예를 들어 :

    // 10 minutes 
    pcntl_alarm(600); 
    pcntl_signal('SIGALRM', function() { print("I am done!\n"); exit(0); }); 
    

    이에 대한 자세한 내용은 여기 PHP 설명서를 참조하십시오 : http://php.net/manual/en/function.pcntl-alarm.php

    +2

    다음은 완벽한 구현 예입니다. https://gist.github.com/avalanche123/3085581 –