2013-03-01 20 views
7

Próbuję wyeksportować kilka skrzynek pocztowych do bazy danych. Mój obecny skrypt połączy IMAP i zapętnieje wszystkie wiadomości. Jednak przy większych skrzynkach pocztowych to nie zadziała i zwolni lub nawet się zatrzyma.PHP pobrać ponad 20000 wiadomości IMAP

Chodzi o to, aby codziennie uruchamiać skrypt, aby "skopiować" wszystkie wiadomości, które nie są jeszcze w bazie danych do bazy danych. Co jest najlepszym sposobem, aby pobrać duże ilości wiadomości e-mail (20k maile rozłożone na około 40 - 50 folderów).

W końcu będzie to wymagać pracy z jednego serwera, aby skanować setki lub nawet tysiące kont dziennie (więc wyobraź sobie ilość danych). Przechuje on pocztę (uid i subject) w bazie danych i utworzy pakiet, który będzie przechowywany na serwerze danych (musi więc również pobrać załączniki).

Odpowiedz

2

Czy używasz imap_ping?

imap_ping() wysyła sygnał do strumienia, aby sprawdzić, czy nadal jest aktywny. To może odkryć nową pocztę; jest to preferowana metoda okresowego sprawdzania poczty "new " oraz "keep alive" dla serwerów, które mają limit czasu nieaktywności wynoszący .

Inne nich patrzeć: imap_timeoutimap_reopen

rzeczywistości nie jest to metoda zwana reopen sugeruje coś prawda :)

Innym rozwiązaniem, które przychodzi na myśl, jeśli tylko mogą” Wydaje się, że utrzymujesz połączenie, aby wyeksportować dane do formatu mbox i dostać się do niego lokalnie. Może być szybszy w przypadku dużej skrzynki pocztowej i może usunąć problemy z przekroczeniem limitu czasu/połączenia.

+0

Musi mieć możliwość połączenia kilku różnych serwerów, więc lokalnie nie jest to opcja niefortunnie. Chodzi o to, aby jednorazowo otrzymać wszystkie "nowe" wiadomości e-mail. Ale jak mogę się upewnić, że bez pętli (i sprawdzenia, czy istnieją w bazie danych) znowu je wszystkie? – Floris

+0

ah, czyli łatwy IMAP ma "widzialną" flagę, prawda? Powinna również istnieć sekwencja ... 'msgno'? Ewentualnie przesyłaj wiadomości e-mail do archiwum, które można przetworzyć i zniszczyć po przetworzeniu. Opisujesz powszechny przypadek użycia dla protokołu IMAP. – ficuscr

+0

Skrzynki pocztowe zostaną "zarchiwizowane" w bazie danych, więc niewidoczne/widoczne flagi nie będą działać. – Floris

5

Więc chcesz wykonać kopie zapasowe wiadomości e-mail przez IMAP. Dostępne są profesjonalne narzędzia programowe.

Zacznijmy od czegoś prostego: pobieranie wiadomości e-mail dla jednego konkretnego użytkownika z folderu skrzynki odbiorczej. Wymaga to (a) zalogowania się przy użyciu poświadczeń użytkownika, (b) wybrania folderu INBOX i (c) pobrania wiadomości (załóżmy, że znasz już jego UID, czyli 55). Można to zrobić w następujący sposób IMAP (tylko żądania - Odpowiedzi nie pokazano):

01 LOGIN username password 
02 SELECT INBOX 
03 UID FETCH 55 BODY[] 

Każda wiadomość w określonym folderze jest podana UID. Jest to unikalny identyfikator dla wiadomości, która nigdy się nie zmienia - nie może być używana przez żadną inną wiadomość w tym folderze. Nowe wiadomości muszą mieć wyższy identyfikator UID niż poprzednie. Dzięki temu jest to przydatne narzędzie do ustalenia, czy poprzednio pobrano już wiadomość.

Następny krok: spójrzmy teraz na pobieranie wszystkich nowych wiadomości w folderze INBOX. Załóżmy, że jesteś pobierania wiadomości po raz pierwszy, a SKRZYNKA obecnie ma wiadomości z UID 54, 55 i 57. Można pobrać te wiadomości naraz używając polecenia takie jak:

03 UID FETCH 54,55,57 BODY[] 

(You może to zepsuć partiami (np. 30 na raz), jeśli jest dużo do pobrania.) Po wykonaniu tej czynności przechowuje się najwyższy UID pobrany do tej pory.Następnym razem, można sprawdzić UID wyższe niż w następujący sposób:

04 UID FETCH 58:* UID 

To będzie pobierać UID (tylko) dla komunikatów z UID od 58 roku. Jeśli uzyskasz wyniki, pobierz je i ponownie zapisz UID. I tak dalej.

Jest jeden haczyk. Identyfikatory UID komunikatu są poprawne, o ile atrybut UIDVALIDITY folderu (zawarty w odpowiedzi na polecenie SELECT) nie zmienia się. Jeśli to się zmieni z jakiegoś powodu, folder zostanie unieważniony i musisz pobrać wszystkie wiadomości z tego folderu od nowa.

Wreszcie, chcesz rozszerzyć to działanie dla wszystkich folderów dla wszystkich użytkowników. W celu uzyskania wszystkich folderów dla danego użytkownika, należy użyć komendy LIST IMAP:

05 LIST "" "*" 

będzie trzeba wiedzieć poświadczenia dla użytkowników wcześniej i pętli nad nimi.

To jest teoria IMAP stojąca za tym, co musisz zrobić. Wdrożenie go w PHP jest pozostawione jako ćwiczenie.

+1

Mogę je pobrać w partiach z cronjob, który działa co minutę i sprawdza, czy jest partia do przetworzenia. Choć moja aplikacja będzie musiała sprawdzić ponad 1k - 5k skrzynek IMAP i pobrać wszystkie nowe wiadomości co najmniej raz dziennie. Zakładając, że w skrzynkach IMAP będzie średnio około 10 tys. Wiadomości rozłożonych średnio na 50 folderów, importowanie potrwa długo? Czy jest jakiś sposób, aby przyspieszyć to z PHP? Czy 25x cronjob (rozpoczynanie wszystkich @ różnych skrzynek) przyspieszy proces o 25x? – Floris

+0

Chcesz pobrać duże ilości danych, a będziesz musiał sobie radzić z ograniczeniami tego. Bez wątpienia będziecie ograniczeni ilością mocy obliczeniowej i przepustowości dostępnej dla was ... abyście mogli wypróbować niektóre optymalizacje (jak wspomniano, równoległe wykonywanie zadań), ale w pewnym momencie nadal osiągniecie limit i nie będziecie w stanie przyspieszyć rzeczy. Zalecam regularne uruchamianie mniejszych zadań (a nie raz dziennie), więc kwota do pobrania jest stosunkowo niewielka i przyrostowa. – Gigi

+0

Zakładam też, że przez 10k wiadomości odnosisz się do pobierania po raz pierwszy wszystkich wiadomości. Tak, to zajmie trochę czasu. Nadal będziesz jednak ograniczony przez swoje zasoby. Możliwe, że wiele komputerów równolegle archiwizuje różne konta. – Gigi