2010-07-17 9 views
4

누구나 연결을 닫는 방법을 알고 있지만 (단지 ?) 나중에 코드를 계속 실행하십시오.PHP에서 연결을 닫지 만 스크립트를 계속 실행하십시오.

페이지를 완료 한 후에 발생할 수있는 긴 프로세스를 클라이언트가 보지 못하도록하고 싶습니다.

+2

? PHP는 정상적인 스크립트를 실행하는데 단지 수 밀리 초 밖에 걸리지 않습니다. 오래 걸리는 것은 일반 대중이 접근 할 수 없어야합니다. – Starx

+1

왜 당신이 너무 필요 무엇을 연결 – animuson

+0

animuson, 귀하의 성명서에 일반적으로 동의하지만,이 신청서/웹 사이트가 일반인이 액세스 할 수 있는지 여부는 알 수 없습니다. 그것은 어딘가에서 내부적으로 실행되는 애플리케이션 일 수 있습니다. 그래서 당신의 의견의 관련성을 보지 못했습니다 ... – kander

답변

9

pcntl_fork()을보고 싶을 수도 있습니다. 현재 스크립트를 포크하고 별도의 스레드에서 실행할 수 있습니다.

사용자가 파일을 업로드 한 다음 타사 서버와의 통신을 포함하여 스크립트가 다양한 작업을 수행하는 프로젝트에서이 파일을 사용했습니다. 시간이 오래 걸릴 수 있습니다. 초기 업로드 후 스크립트는 사용자에게 다음 페이지를 분기하여 표시하고 부모는 스스로를 종료합니다. 그런 다음 아이는 실행을 계속하고 반환 된 페이지에서 AJAX를 사용하여 상태를 쿼리합니다. 응용 프로그램을 훨씬 더 응답하게 만들었고 사용자는 실행 중일 때 상태에 대한 피드백을 받았습니다. 당신이 pcntl_fork을 사용할 수없는 경우

, 당신은 항상 신속하게 페이지를 돌아 다시 떨어질 수는 AJAX 요청을 발생시킵니다 :

이 링크는 더에 방법을 사용한다 대기열에서 더 많은 항목을 실행합니다.하지 fork 전체 아파치 웹 서버를 수행, 대신 별도의 프로세스를 시작합니다


mvds는 (특정 서버 구성에 적용 할 수있는) 다음을 생각 나게한다. 그 과정을 통해 사는 아이를 포크로 만들자. proc_open에 대한 귀하의 PHP 스크립트와 프로세스 사이의 완전한 fd 상호 작용을 찾으십시오.

+0

php 자체로 작성된 맞춤형 http 서버로만 pcntl_fork() (이 문맥에서)를 사용할 수 있습니다. 따라서 일반적으로이 응답은 약 0.0001 %) – nathan

+0

아파치를 사용하고있었습니다. – Jhong

+0

그러면 내가 생각한 전체 아파치 데몬을 포크합니다. 그것은 꽤 광경이 아니며 아파치 모듈의 의도 된 용도가 아닐 것입니다 ... – mvds

5

나는 클라이언트가 페이지가 완료된 후 발생할 수있는 긴 과정을보고 싶지 않아. 후 긴 과정이 완료 될 때까지

슬프게도, 페이지가 수행되지 않습니다 - 따라서 당신을 위해 무엇을 요구하는 것은 불가능하다 난 두려워 (당신이을 추론하는 방식으로 구현).

Jhong의 답변에 의해 지적되고 animusen의 의견에 의해 반대로 제안되는 핵심은 웹 개발자로서 HTTP에서 우리가하는 일의 요점은 가능한 한 빨리 요청에 응답하는 것입니다. 그래서 당신이 다른 일을한다면, 아마도 약간 더 나은 디자인 결정을 내릴 것입니다. :)

일반적으로 '페이지'를 반환 한 후 수행하고있는 추가 작업을 수행하고 넘겨줍니다 다른 프로세스로, 일반적으로 작업 대기열에 작업을 배치하고 cli 데몬이나 cron 작업을 가져와 필요한 작업을 수행하는 것을 의미합니다.

정확한 해결책은하고있는 일과 다른 (일련의) 질문에 대한 답변입니다. 하지만이 문제를 해결하려면 연결을 종료 할 수 없으며 스크립트/페이지에서 장기 실행 프로세스를 리팩토링하는 것이 좋습니다.

3

전체 아파치 웹 서버를 fork하지 마십시오. 대신 별도의 프로세스를 시작하십시오. 그 과정을 통해 사는 아이를 포크로 만들자. proc_open에 대한 귀하의 PHP 스크립트와 프로세스 사이의 전체 fd 상호 작용을 찾으십시오.

+0

이것은 기존 답변에 추가 된 가능성이 있습니다. 특히 pcntl_fork가 아파치 SAPI 모듈 사용 내에서 매우 특별한 Apache + PHP에서 뭔가 나쁜/리소스를 많이 사용한다는 두려움이 있습니다. 이는 기존 답변에 대한 설명이거나 추가 답변이 아닌 해당 답변을 사용할 때 고려해야 할 사항에 대한 추가 수정 사항이어야합니다. 이는 가치있는 것이 분명하지 않기 때문입니다. 나는 그것을 합병했고 나는 그것을 삭제할 것을 요구한다. 또한 더 많은 것을 생각하고있을 때 PHP에서 '포크 (fork)'라고하는 링크와 같이 더 잘 설명하는 참조가 있어야합니다. – hakre

+0

@hakre 나는 당신과 동의하지 않습니다. 문제는 "PHP 스크립트를 실행 한 후 코드를 실행하는 방법"이며 대답은 "대신 별도의 프로세스를 시작하는 것입니다. 프로세스가 PHP를 실행하는 자식을 포크로 만듭니다 .proc_open이 PHP 스크립트 그리고 그 과정. " – mvds

+0

@ hakre, 동의하지 않으면 간단하게 downvote, 이것이이 사이트의 작동 방식입니다. – mvds

4

PHP's ignore_user_abort-setting을 살펴보십시오. ignore_user_abort() function을 사용하여 설정할 수 있습니다.

example of (optional) use이 주어졌다 (그리고 OP에 의해 작동보고 된 바있다) 다음과 같은 중복 된 질문 :

그것은 기본적으로 PHP 설명서에 사용자가 노트에 대한 참조를 제공합니다 .

+0

이것은 실제적인 최선의 답변입니다. 그는 클라이언트가 프로세스의 결과를 알 필요가 없으므로 fork, queue 또는 그와 같은 것을 사용할 필요가 없다고 말합니다. – pjbeardsley

+0

@pjbeardsley : 실제로 이것은 가장 좋은 대답이 아닙니다. 몇 가지 문제가 생겨 났기 때문입니다. 우선 * ingnore_user_abort는 * 링크 된 소스에 따라 선택 사항이지만 첫 번째로 필요한 이름이 붙었습니다. 둘째로, 여기에 제시된 대답은 일찌감치 제시되었고 연결되지 않았습니다. 또한 소스 코드가 누락되었습니다 (이것은 링크 된 복제본의 문제 였지만 현재는 수정되었습니다). 그러나 링크 된 예제는 웹 서버/PHP 구성에 대해 말하는 것을 매우 잘 수행하며 그렇게하는 일종의 * 공통 *입니다. 그래서 완전히 나쁜 대답은 아닙니다. – hakre

2

해결했습니다. 이 문제는 수행해야 할 작업을 작업 대기열에 넣은 다음 cron 스크립트에서 백엔드 작업을 정기적으로 받도록하십시오. 아마 당신이 필요로하는 것은 아니 겠지만, 데이터 집약적 인 프로세스에서는 잘 작동합니다.

(당신은 시도 및 테스트 솔루션을 현금 뭉치를 가지고하고 싶은 한 경우 당신은 또한, 젠드 서버의 작업 대기열을 사용할 수 있습니다)

관련 문제