2011-01-16 4 views
2

사용자가 특정 스레드를 구독 할 수있는 포럼이 있습니다. 누군가가 스레드에 응답하면 DB에 응답이 추가되고 성공 페이지가 표시되기 전에 모든 구독자에게 전자 메일 경고가 전송됩니다.루프에서 PHP 메일을 사용하면 페이지가 표시 될 때까지 기다려야합니다.

FYI - PHP의 메일 기능을 사용하지 않습니다. 호스팅 제공 업체의 시간 제한은 500입니다. 나는 Google App Engine을 사용하여 컬을 통해 이메일을 발송합니다.

문제 - 구독자 수가 100 명을 넘으면 성공 페이지가 표시되기까지 사용자가 너무 오래 기다려야합니다. PHP는 각 구독자를 먼저 반복해야하기 때문입니다. DB에 전자 메일을 삽입 한 다음 cron을 통해 처리하는 방법을 사용하지 않고이를 우회 할 수있는 방법이 있습니까?

희망 나는 이해했습니다. 미리 감사드립니다.

답변

2

메일 스크립트를 작성하여 쉘 명령을 사용하여 백그라운드에서 실행되도록 할 수 있습니다. PHP의 shell_exec 기능을 사용

shell_exec("/path/to/php /path/to/send_notifications.php 'var1' 'var2' >> /path/to/alert_log/paging.log &"); 

, 당신은 백그라운드에서 스크립트를 실행하기 위해 PHP를 알 수 있습니다. shell_exec 명령에 표시되는 매개 변수는 공백으로 구분됩니다.

  • /path/to/php - 당신이 보낼 수 $_SERVER['argv'] 변수 - 메일 스크립트에
  • 'var1' 'var2'을 경로 - 서버에서 PHP의 실제 경로
  • /path/to/send_notifications.php (당신은 여기에 'PHP'를 사용할 수 있어야합니다) 스크립트에 대한 경로 다음에 작은 따옴표로 묶어 놓습니다.
  • >> /path/to/alert_log/paging.log
  • - 이것의 가장 중요한 부분 - (선택 사항) 로그 파일의 경로는 메일 스크립트에서 echo'ed 것도이 파일
  • &에 기록됩니다. & 당신이 메일 스크립트를 실행할 때, 이런 식으로 이렇게 배경

에서이 스크립트를 실행하는 서버를 말한다, 양식을 제출하는 사용자는 스크립트가 끝날 때까지 기다릴 필요가 없습니다. 브라우저는 페이지를 더 빠르게로드하고 사용자는 확인 페이지에서 멀리 탐색하거나 브라우저를 닫을 수 있으며 스크립트는 완료 될 때까지 계속 실행됩니다.

+1

좋지만 호스팅 제공 업체는 php – Dmitri

+0

에서 명령 줄 스크립트를 실행할 때 이러한 유형의 실행을 허용하지 않을 수 있습니다. 스크립트가 인터넷에서 도달 할 수있는 디렉토리에 있지 않거나 다른 사람이 메일 기능을 오용 할 수 있는지 확인하십시오. – Joost

+0

이것은 유망 해 보인다! 내 호스트가 shell_exec를 지원한다는 것을 확인했습니다. 지금 시도해보십시오 - 빠른 질문, Windows에서이 작업이 가능합니까? (내 개발 플랫폼은 창이지만 내 웹 사이트는 유닉스에서 호스팅됩니다.) – Dickinson

0

아니요, GAE 헤이븐에 대한 모든 API 호출이 실행되기 전에 PHP 프로세스가 종료되지 않습니다. 스크립트가 실행되는 동안 당신은 그러나 사용자에게 상태 업데이트를 보낼 수 :

// in loop 
// sent one message 

echo "Sent email to user $email_user \n"; 
ob_flush(); 

ob_flush() 클라이언트에 현재의 버퍼를 보내도록 아파치를 강제 할 것이다. 또는 메일 페이지를 <div>에 표시하고 ajax를 통해 메일 스크립트를 호출 할 수도 있습니다.

편집 : 내가 GAE에 일괄 적으로 메시지를 보낼 수 있어야한다고 생각하십니까? GAE 끝 (Python/Java)에 어떤 종류의 시스템이 있습니까?

+0

GAE에서 Python을 사용하면 일괄 처리로 단일 API 호출을 통해 여러 이메일을 보내겠습니까? GAE를 사용하는 것이 가능한지 나는 모른다. 그렇습니까? – Dickinson

+0

저는 Ajax 옵션을 좋아합니다. 이전에는 그렇게 생각하지 않았습니다. 그러나 그것은 사용자가 자바 스크립트를 끄면 이메일이 전혀 전송되지 않는다는 것을 의미합니다 ... – Dickinson

+0

정말 Ajax를 사용하여 이런 종류의 작업을 할 수 있습니다. 그런 다음 전자 메일을 보낼지 여부는 클라이언트에 의존하며 사용자가 실제로 뭔가 게시했는지 확인하는 것이 어렵습니다. 그렇지 않으면 모든 사람이 메일 스크립트에 요청하여 수십 개의 메일을 보낼 수 있습니다. – Joost

0

나는 cron이 아니어야한다고 생각하지 않지만 오프라인으로 처리하려면 the task queue을 사용해야합니다!

애플리케이션 엔진 어플리케이션은 큐로 (웹 후크로 모델링) 작업 삽입하여 배경 처리를 수행 할 수있다. App Engine은 새 작업이 준비되어 있고 작업을 감지하고 실행을 위해 을 자동으로 보내고 일정을 예약합니다. 합니다 (작업 대기열에)은 webhook에서

당신은 당신의 웹 서비스와가 완료 될 때까지 기다릴 필요가 없습니다 사용자를 보장 비동기 될 것이다 호출하는이 방법에 asynchronous fetch을 만들 수 있습니다. 당신이 내 해결책을 이해하기를 바랍니다.

+0

그냥 체크 아웃했다. 문제는 PHP를 사용하여 GAE에 액세스했기 때문이다. PHP가 작업 대기열에 모든 이메일을 추가해야하는데 느리다 ... 또는 잘못 되었나요? – Dickinson

+0

나는 taskqueue.add 호출이 매우 비동기 적이라고 믿습니다! – Alfred

0

문제는 구현과 관련이 있다고 생각합니다. 특히 많은 양의 메일을 보내려면 forking 또는 지연된 작업을하는 것이 가장 좋습니다. 포크 뒤에있는 아이디어는 "작업"을 대기열에 넣고 나중에 실행하는 것입니다. 클라이언트가 프로세스가 완료 될 때까지 기다리지 않아도됩니다 ...

PHP에서 가장 많이 사용되는 프로젝트 중 하나는 gearman입니다.

이 방법의 몇 가지 다른 장점

은 다음과 같습니다
  • 빠르게 등 쓰레기 수집에 사용자 정의 스크립트를 작성할 수 있습니다
  • 페이지의 봉사

    1. 오류 캐싱 및 자동 재시도 ...
  • +0

    공유 서버에 있습니다 :-(- gearman을 설치할 수 없으며 빠른 검색 결과 포크를 시도한 다른 사용자가 스크립트를 일시 중단 한 결과가 표시됩니다 .. – Dickinson

    +2

    다음 호스트가됩니다. 귀하의 요청을 처리 할 수 ​​없으므로 다른 호스팅 제공 업체로 이동해야합니다 ... – sethvargo

    +0

    +1 호스트를 스위칭 할 수 있습니다. 공유 서버에서 실행할 수있는 것은 아니며 DV는 꽤 값 싸게 요즘입니다. – prodigitalson

    0

    이메일 전송을 별도의 스크립트로 이동해야합니다. 이 작업을 수행하는 한 가지 방법은 mail_queue 테이블을 만드는 것입니다. 루프 내부에서 데이터베이스에 행을 작성하기 만하면됩니다.

    그런 다음 다른 스크립트에서 데이터베이스의 이메일 집합을 반복하여 보내면됩니다. 이 스크립트는 cron 작업에 의해 실행될 수 있으며, 해당 행을 '보낸'것으로 업데이트 할 수 있습니다.

    +0

    예, a cron은 유일한 해결책처럼 보였습니다. 다른 응답이 없으면 감사 할 것입니다. 감사합니다! – Dickinson

    1

    php를 php-pfm에서 제어하는 ​​fastcgi로 사용하는 경우 fastcgi_finish_request() 함수를 사용할 수 있습니다. 그것은 매우 강력한 기능입니다. 호출 할 때 브라우저 연결을 닫지 만 나머지 스크립트는 계속 실행합니다.

    이 기능을 처음 발견 한 이후로 나는 그것을 사용하고 사랑했습니다.

    관련 문제