HTTP 응답을 보낸 후 PHP 처리 계속
PHPHTTP 응답을 보낸 후 PHP 처리 계속
내 스크립트는 서버에 의해 호출됩니다. 서버에서 ID_OF_MESSAGE 및 TEXT_OF_MESSAGE를 받게됩니다.
필자의 스크립트에서는 들어오는 텍스트를 처리하고 params : ANSWER_TO_ID 및 RESPONSE_MESSAGE를 사용하여 응답을 생성합니다.
문제는 내가 "ID_OF_MESSAGE"에 대한 응답을 보내고 있지만 처리 할 메시지를 보내는 서버가 HTTP 응답 200을받은 후 자신에게 전달 된 메시지를 설정한다는 것입니다.
해결책 중 하나는 메시지를 데이터베이스에 저장하고 매 분마다 실행될 일부 cron을 만드는 것이지만 즉시 응답 메시지를 생성해야합니다.
거기에 몇 가지 솔루션을 서버 HTTP 응답 200 보내고 PHP 스크립트를 계속 실행하는 것보다 있습니까?
정말 고마워
해결법
-
==============================
1.예. 당신은 이것을 할 수 있습니다 :
예. 당신은 이것을 할 수 있습니다 :
ignore_user_abort(true); set_time_limit(0); ob_start(); // do initial processing here echo $response; // send the response header('Connection: close'); header('Content-Length: '.ob_get_length()); ob_end_flush(); ob_flush(); flush(); // now the request is sent to the browser, but the script is still running // so, you can continue...
-
==============================
2.ignore_user_abort (true)를 사용하여 제안하는 많은 응답을 여기에서 보았습니다. 그러나이 코드는 필요하지 않습니다. 이 모든 것은 브라우저가 닫히거나 요청을 중지하기 위해 escape 키를 눌러 사용자가 중단 된 경우 응답을 보내기 전에 스크립트가 계속 실행되도록합니다. 그러나 그것은 당신이 요구하는 것이 아닙니다. 응답이 전송 된 후 계속 실행을 요청하는 중입니다. 필요한 것은 다음과 같습니다.
ignore_user_abort (true)를 사용하여 제안하는 많은 응답을 여기에서 보았습니다. 그러나이 코드는 필요하지 않습니다. 이 모든 것은 브라우저가 닫히거나 요청을 중지하기 위해 escape 키를 눌러 사용자가 중단 된 경우 응답을 보내기 전에 스크립트가 계속 실행되도록합니다. 그러나 그것은 당신이 요구하는 것이 아닙니다. 응답이 전송 된 후 계속 실행을 요청하는 중입니다. 필요한 것은 다음과 같습니다.
// Buffer all upcoming output... ob_start(); // Send your response. echo "Here be response"; // Get the size of the output. $size = ob_get_length(); // Disable compression (in case content length is compressed). header("Content-Encoding: none"); // Set the content length of the response. header("Content-Length: {$size}"); // Close the connection. header("Connection: close"); // Flush all output. ob_end_flush(); ob_flush(); flush(); // Close current session (if it exists). if(session_id()) session_write_close(); // Start your background work here. ...
백그라운드 작업이 PHP의 기본 스크립트 실행 시간 제한보다 오래 걸리는 것이 염려되는 경우 set_time_limit (0); 상단에.
-
==============================
3.FastCGI 처리 또는 PHP-FPM을 사용하는 경우 다음을 수행 할 수 있습니다.
FastCGI 처리 또는 PHP-FPM을 사용하는 경우 다음을 수행 할 수 있습니다.
session_write_close(); //close the session fastcgi_finish_request(); //this returns 200 to the user, and processing continues // do desired processing ... $expensiveCalulation = 1+1; error_log($expensiveCalculation);
출처 : http://fi2.php.net/manual/en/function.fastcgi-finish-request.php
-
==============================
4.나는이 문제에 대해 몇 시간을 보냈고 Apache와 Nginx에서 작동하는이 함수를 사용했다.
나는이 문제에 대해 몇 시간을 보냈고 Apache와 Nginx에서 작동하는이 함수를 사용했다.
/** * respondOK. */ protected function respondOK() { // check if fastcgi_finish_request is callable if (is_callable('fastcgi_finish_request')) { /* * This works in Nginx but the next approach not */ session_write_close(); fastcgi_finish_request(); return; } ignore_user_abort(true); ob_start(); $serverProtocole = filter_input(INPUT_SERVER, 'SERVER_PROTOCOL', FILTER_SANITIZE_STRING); header($serverProtocole.' 200 OK'); header('Content-Encoding: none'); header('Content-Length: '.ob_get_length()); header('Connection: close'); ob_end_flush(); ob_flush(); flush(); }
오랜 처리 전에이 기능을 호출 할 수 있습니다.
-
==============================
5.@vcampitelli의 대답을 약간 수정했습니다. 가까운 머리글이 필요하다고 생각하지 마십시오. Chrome에서 중복 된 닫기 헤더를보고있었습니다.
@vcampitelli의 대답을 약간 수정했습니다. 가까운 머리글이 필요하다고 생각하지 마십시오. Chrome에서 중복 된 닫기 헤더를보고있었습니다.
<?php ignore_user_abort(true); ob_start(); echo '{}'; header($_SERVER["SERVER_PROTOCOL"] . " 202 Accepted"); header("Status: 202 Accepted"); header("Content-Type: application/json"); header('Content-Length: '.ob_get_length()); ob_end_flush(); ob_flush(); flush(); sleep(10);
-
==============================
6.나는 2012 년 4 월 Rasmus Lerdorf에게이 기사를 인용하여이 질문을 던졌다.
나는 2012 년 4 월 Rasmus Lerdorf에게이 기사를 인용하여이 질문을 던졌다.
필자는 플랫폼에 추가 출력 (stdout에?)이 생성되지 않는다는 것을 알려주는 새로운 PHP 내장 함수를 개발할 것을 제안했습니다. (그러한 함수는 연결을 닫을 수 있습니다.) 라스무스 레르 도르프 (Rasmus Lerdorf)
나는 그의 요점을 볼 수 있으며, 일부 응용 프로그램 / 로딩 시나리오에 대한 그의 견해를지지합니다! 그러나 일부 다른 시나리오에서는 vcampitelli 외의 솔루션이 좋습니다.
-
==============================
7.어떤 확실하지 않은 이유로 MAMP PRO (Apache, MySQL, PHP)를 사용할 때 이러한 솔루션이 작동하지 않습니다.
어떤 확실하지 않은 이유로 MAMP PRO (Apache, MySQL, PHP)를 사용할 때 이러한 솔루션이 작동하지 않습니다.
-
==============================
8.나는 이것을 위해 register_shutdown_function 함수를 사용한다.
나는 이것을 위해 register_shutdown_function 함수를 사용한다.
void register_shutdown_function ( callable $callback [, mixed $parameter [, mixed $... ]] )
http://php.net/manual/en/function.register-shutdown-function.php
편집 : 위의 작동하지 않습니다. 나는 오래된 문서들에 속아 넘어 갔다. register_shutdown_function의 동작이 PHP 4.1 링크 링크 이후로 변경되었습니다.
-
==============================
9.응답 헤더를 변경하고 싶지 않은 경우에는 다른 접근 방법과이를 고려해 볼 가치가 있습니다. 다른 프로세스에서 스레드를 시작하면 호출 된 함수는 응답을 기다리지 않고 최종 HTTP 코드가있는 브라우저로 돌아갑니다. pthread를 구성해야합니다.
응답 헤더를 변경하고 싶지 않은 경우에는 다른 접근 방법과이를 고려해 볼 가치가 있습니다. 다른 프로세스에서 스레드를 시작하면 호출 된 함수는 응답을 기다리지 않고 최종 HTTP 코드가있는 브라우저로 돌아갑니다. pthread를 구성해야합니다.
class continue_processing_thread extends Thread { public function __construct($param1) { $this->param1 = $param1 } public function run() { //Do your long running process here } } //This is your function called via an HTTP GET/POST etc function rest_endpoint() { //do whatever stuff needed by the response. //Create and start your thread. //rest_endpoint wont wait for this to complete. $continue_processing = new continue_processing_thread($some_value); $continue_processing->start(); echo json_encode($response) }
$ continue_processing-> start ()를 실행하면 PHP는이 스레드의 반환 결과를 기다리지 않으므로 rest_endpoint가 고려됩니다. 끝났어.
pthreads에 도움이되는 링크
행운을 빕니다.
-
==============================
10.php file_get_contents를 사용하는 경우 연결 닫기만으로는 충분하지 않습니다. PHP는 여전히 서버에 의해 보내 마녀를 기다립니다.
php file_get_contents를 사용하는 경우 연결 닫기만으로는 충분하지 않습니다. PHP는 여전히 서버에 의해 보내 마녀를 기다립니다.
내 솔루션은 'Content-Length :'를 읽는 것입니다.
샘플은 다음과 같습니다.
response.php :
<?php ignore_user_abort(true); set_time_limit(500); ob_start(); echo 'ok'."\n"; header('Connection: close'); header('Content-Length: '.ob_get_length()); ob_end_flush(); ob_flush(); flush(); sleep(30);
닫는 줄에 응답하여 "\ n"에 주목하고, wait eof 동안 읽은 fget이 아니라면.
read.php :
<?php $vars = array( 'hello' => 'world' ); $content = http_build_query($vars); fwrite($fp, "POST /response.php HTTP/1.1\r\n"); fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n"); fwrite($fp, "Content-Length: " . strlen($content) . "\r\n"); fwrite($fp, "Connection: close\r\n"); fwrite($fp, "\r\n"); fwrite($fp, $content); $iSize = null; $bHeaderEnd = false; $sResponse = ''; do { $sTmp = fgets($fp, 1024); $iPos = strpos($sTmp, 'Content-Length: '); if ($iPos !== false) { $iSize = (int) substr($sTmp, strlen('Content-Length: ')); } if ($bHeaderEnd) { $sResponse.= $sTmp; } if (strlen(trim($sTmp)) == 0) { $bHeaderEnd = true; } } while (!feof($fp) && (is_null($iSize) || !is_null($iSize) && strlen($sResponse) < $iSize)); $result = trim($sResponse);
보시다시피,이 스크립트는 콘텐츠 길이에 도달하면 eof를 기다리지 않습니다.
도움이되기를 바랍니다.
-
==============================
11.압축 할 수 있고 응답을 보내고 다른 PHP 코드를 실행할 수있는 무언가가 있습니다.
압축 할 수 있고 응답을 보내고 다른 PHP 코드를 실행할 수있는 무언가가 있습니다.
function sendResponse($response){ $contentencoding = 'none'; if(ob_get_contents()){ ob_end_clean(); if(ob_get_contents()){ ob_clean(); } } header('Connection: close'); header("cache-control: must-revalidate"); header('Vary: Accept-Encoding'); header('content-type: application/json; charset=utf-8'); ob_start(); if(phpversion()>='4.0.4pl1' && extension_loaded('zlib') && GZIP_ENABLED==1 && !empty($_SERVER["HTTP_ACCEPT_ENCODING"]) && (strpos($_SERVER["HTTP_ACCEPT_ENCODING"], 'gzip') !== false) && (strstr($GLOBALS['useragent'],'compatible') || strstr($GLOBALS['useragent'],'Gecko'))){ $contentencoding = 'gzip'; ob_start('ob_gzhandler'); } header('Content-Encoding: '.$contentencoding); if (!empty($_GET['callback'])){ echo $_GET['callback'].'('.$response.')'; } else { echo $response; } if($contentencoding == 'gzip') { if(ob_get_contents()){ ob_end_flush(); // Flush the output from ob_gzhandler } } header('Content-Length: '.ob_get_length()); // flush all output if (ob_get_contents()){ ob_end_flush(); // Flush the outer ob_start() if(ob_get_contents()){ ob_flush(); } flush(); } if (session_id()) session_write_close(); }
from https://stackoverflow.com/questions/15273570/continue-processing-php-after-sending-http-response by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
PHP에서 404에 대한 URL을 테스트하는 쉬운 방법은 무엇입니까? (0) | 2018.09.12 |
---|---|
PHP 함수 오버로딩 (0) | 2018.09.12 |
PHP에서 비동기 GET 요청을하는 방법은 무엇입니까? (0) | 2018.09.12 |
사람들이 플래시 게임의 PHP 기반 최고 점수 테이블을 해킹하는 것을 막는 가장 좋은 방법은 무엇입니까? (0) | 2018.09.12 |
Big-O for PHP 함수 목록 (0) | 2018.09.12 |