Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyciąganie adresów e-mail za pomocą imap problem z tablicą
Forum PHP.pl > Forum > PHP
maraska
Witam. Chciałem wyciągnąć i zapisać do bazy adresy e-mail znajdujące się w body przychodzących wiadomości.
W ten sposób
  1. .....
  2. $emails = imap_search($inbox,'ALL');
  3.  
  4. if($emails) {
  5. foreach($emails as $email_number) {
  6.  
  7. $message = imap_fetchbody($inbox,$email_number,1.2);
  8. preg_match_all("/([w.+-]+)@([a-zA-z0-9.-]+).(w{2,6})/", $message, $wynik);
  9.  
  10. foreach ($wynik as &$value){
  11. echo '<pre>';
  12. print_r($value);
  13. echo '</pre>';
  14.  
  15. //zapis do bazy


Łączy się ze skrzynką, zlicza maile ale nie wiem jak rozwiązać problem tablic w pętli.
W body każdej wiadomości może być kilka adresów e-mail.

print_r($value); daje:

<pre>Array
(
)
</pre><pre>Array
(
)
</pre><pre>Array
.......

Z góry dziękuję za pomoc
trzczy
Co daje
  1. var_dump($wynik);


edit:
Regex powinien być taki (pogubiłeś ukośniki)
  1. [\w.+-]+@[a-zA-z0-9.-]+\.\w{2,6}

https://regex101.com/r/MVyOEw/1/
maraska
Dziękuję za pomoc. Już widzę, że preg_match_all źle działa nawet po wdrożeniu Twoich poprawek bo zwraca z var_dump($wynik); i adresy email i takie

string(3) "bok"
[6]=>
string(3) "bok"
[7]=>
string(32) "4bc4570b8428b3157e8fbad138aa2809"
[8]=>
string(3) "bok"
}
[2]=>
array(9) {
[0]=>
string(5) "sopro"
[1]=>
string(5) "sopro"
[2]=>
string(8) "sopro.pl"
[3]=>
string(8) "sopro.pl"
[4]=>
string(8) "sopro.pl"

poszukam czegoś nowego i albo wrócę z rozwiązaniem dla innych albo z kolejnym pytaniem
trzczy
Chyba się jakoś pogubiłeś jednak. Zobacz jak to działa ładnie:
  1. <?php
  2. $text = <<<'AHA'
  3. ewfda fdffdsfddsa fdsaf ewewem thurn@live.com rewqreqw
  4. fda fdefhgfjh fdsa fdsaf fangorn@hotmail.com rewqr re q rewqrrwq
  5. fda fdfdf dsa fdsaf euice@outlook.com ewrewqre
  6. fd
  7.  
  8. a f fhjhfdffdsaf fdsa fdsaf rgarcia@optonline.net rewqrewq
  9. fda fdfdsa fdsaf mxiao@yahoo.com rewreqw rewqer
  10. fda fd hffdsa fdsaf firstpr@att.net r ewqrewq
  11. AHA;
  12. $pattern='/\S+@\S+\.\S{1,6}/';
  13. preg_match_all($pattern, $text, $matchArray);
  14. print_r($matchArray[0]);
  15. //Array
  16. //(
  17. // [0] => thurn@live.com
  18. // [1] => fangorn@hotmail.com
  19. // [2] => euice@outlook.com
  20. // [3] => rgarcia@optonline.net
  21. // [4] => mxiao@yahoo.com
  22. // [5] => firstpr@att.net
  23. //)
https://3v4l.org/RsgZA
Sam pattern regexa dodatkowo uprościłem, bo w sumie na internecie jest sporo przykładów na taki pattern, a ostatecznie warto by wiedzieć, jak to reguluje standard. Ja bym to brał takim regexem jak ten tutaj, a potem filter_var dla mejla w php.
  1. filter_var('bob@example.com', FILTER_VALIDATE_EMAIL)
maraska
Dzięki za pomoc trzczy ale z naturalnego maila wychodzi nienajlepiej.

Taki kod z Twoim $pattern:

  1. $emails = imap_search($inbox,'ALL');
  2.  
  3. if($emails) {
  4. foreach($emails as $email_number) {
  5.  
  6. $message = imap_fetchbody($inbox,$email_number,1.2);
  7.  
  8. $pattern='/\S+@\S+\.\S{1,6}/';
  9.  
  10. preg_match_all($pattern, $message, $matchArray);
  11.  
  12. echo 'print_r($matchArray';
  13. print_r($matchArray[0]);
  14.  
  15. foreach ($matchArray[0] as $value){
  16. echo "echo Svalue = $value\n";
  17. echo 'print_r($value';
  18. print_r($value, true);
  19. }
  20.  
  21. }
  22. }


daje taki wynik:

print_r($matchArrayArray
(
[0] => luga.klienta.skarzysko@castorama.pl">obsluga.klienta.skarzysko@castorama.pl=
[1] => <p>obsluga.klienta.skarzysko@castorama.pl<br>
[2] => ##rfc822;obsluga.klienta.skarzysko@bricodepot.pl</p>
[3] => &lt;obsluga.klienta.skarzysko@bricodepot.pl&gt;
[4] => &lt;obsluga.klienta.skarzysko@bricodepot.pl&gt;
[5] => &lt;bok@anonser.eu&gt;
[6] => &lt;bok@anonser.eu&gt;
[7] => &lt;3894b5989a98437667a58858f613a4fd@localhost.locald
[8] => bok@anonser.eu
)
echo Svalue = luga.klienta.skarzysko@castorama.pl">obsluga.klienta.skarzysko@castorama.pl=
print_r($valueecho Svalue = <p>obsluga.klienta.skarzysko@castorama.pl<br>
print_r($valueecho Svalue = ##rfc822;obsluga.klienta.skarzysko@bricodepot.pl</p>
print_r($valueecho Svalue = &lt;obsluga.klienta.skarzysko@bricodepot.pl&gt;
print_r($valueecho Svalue = &lt;obsluga.klienta.skarzysko@bricodepot.pl&gt;
print_r($valueecho Svalue = &lt;bok@anonser.eu&gt;
print_r($valueecho Svalue = &lt;bok@anonser.eu&gt;
print_r($valueecho Svalue = &lt;3894b5989a98437667a58858f613a4fd@localhost.locald
print_r($valueecho Svalue = bok@anonser.eu

Może coś jeszcze pomożecie Panowie (i Panie)
trzczy
Prawda. Mój regex zakładał, że na końcu i początku adresu jest spacja. To było chore założenie. Co do dalszej pomocy to mogę poszukać na internecie, jaki jest najlepszy regex na mejla, za 50zł.
Pyton_000
Masz i szukaj:
https://regex101.com/library?orderBy=RELEVA...mp;search=email
maraska
regex to jedno. Coś można w sieci szukać, coś można potem kombinować z wynikami przez strpos czy coś.
Mnie bardziej martwi to, że te moje foreach dają ostatecznie array zamiast kolejno pojedynczy $email w pętli z którym można by zrobić $qry = mysql_query("UPDATE tabela SET zly_email = 1 WHERE email LIKE $email")

I w tym jakbyście kochani pomogli bo ugrzązłem.
trzczy
Cytat(maraska @ 13.12.2017, 21:08:29 ) *
Mnie bardziej martwi to, że te moje foreach dają ostatecznie array zamiast kolejno pojedynczy $email w pętli

Czekaj... jak masz tablicę stringów, to wewnątrz pętli foreach jest dostęp do każdego stringa jako stringa. Może powinieneś robić zapytanie w środku pętli, a nie czekając na jej koniec.
maraska
Cytat(trzczy @ 14.12.2017, 05:18:53 ) *
Czekaj... jak masz tablicę stringów, to wewnątrz pętli foreach jest dostęp do każdego stringa jako stringa. Może powinieneś robić zapytanie w środku pętli, a nie czekając na jej koniec.


No jasne, wyniki print_r mnie zmyliły.

Poniżej zamieszczam działający skrypt, który wyciąga adresy e-mail z Undelivery i oznacza te adresy w bazie danych jako złe.

Adresy e-mail, które zostały po naszej wysyłce odrzucone - Undelivery są ukryte w body wiadomości.
Jest tam na raz kilka postaci adresów, w tym nasz. Przykład:
[0] => bok@anonse.eu
[1] => jan.piotrow.zurm@wp.pl
[2] => rfc822;jan.piotrow.zurm@wp.pl
[3] => "jan.piotrow.zurm@wp.pl":

Z przejrzenia iluś tam setek wyników wychodzi, że adres o który nam chodzi można identyfikować po "rfc822;" i tak też filtruje ten skrypt.
Być może na innym serwerze jest inaczej, stąd zostawione print_r i echo do testów.
Powyższy "czysty" przykład jest z parsowania body z parametrem "2", dla "1.2" było dużo gorzej.
Wskazany jest podfolder Drafts, bo tam zostały zrzucone do testów wiadomości Undelivery.

Dzięki za pomoc wszystkim z tego tematu


  1. // Skryt do wyciągania adresów e-mail z body zwrotek Undelivery i oznaczania tych adresów w bazie danych jako zły adres.
  2.  
  3. error_reporting(E_ALL & ~E_NOTICE & ~E_USER_NOTICE);
  4.  
  5. require 'cat_name.php'; //tam jest połączenie z bazą danych
  6.  
  7.  
  8. //Połaczenie z kontem email
  9.  
  10. $imap = imap_open("{domena.eu:143}INBOX.Drafts", "bok@domena.eu", "passwd") OR die ("can't connect: " . imap_last_error());
  11.  
  12. /* Odchaszowanie tego wyświetli strukturę INBOX z czego będziemy wiedzieli do jakiego podfolderu chcemy wejść w $imap bo czasami Kosz to naprawdę jest Trash
  13. echo "<h1>Mailboxes</h1>\n";
  14. $folders = imap_listmailbox($imap, "{user@domena.eu:143}", "INBOX");
  15. */
  16.  
  17. //Wyciągnięcie body maili
  18.  
  19. $emails = imap_search($imap,'ALL'); //zamaiast ALL można ustawić nieprzeczytane itp. zob. manual imap
  20.  
  21. if($emails) {
  22. foreach($emails as $email_number) {
  23.  
  24. $message = imap_fetchbody($imap,$email_number,2); //zamiast "2" można testować "1.2", u mnie "2" działa najlepiej
  25.  
  26. $pattern='/\S+@\S+\.\S{1,6}/';
  27.  
  28. preg_match_all($pattern, $message, $matchArray);
  29.  
  30. echo 'print_r($matchArray'; // dotestów
  31. print_r($matchArray[0]); // dotestów
  32.  
  33. foreach ($matchArray[0] as $value){
  34. if(strstr($value, "rfc822;")!==False){
  35. $value = str_replace("rfc822;",'', $value);
  36. echo "echo Svalue = $value\n"; // dotestów
  37.  
  38. $qry = mysql_query("UPDATE `tabela` SET `zly_email` = 1 WHERE `email` LIKE '$value'");
  39. }
  40. }
  41. }
  42. }
  43.  
  44. /* zamykamy połączenie */
  45. //imap_delete($imap,'1:*'); // !!!!!!!!!!! Uwaga, czyścimy całą zawartość skrzynki, tu Drafts, bo tam były same Undelivery
  46. imap_errors();
  47. imap_alerts();
  48. imap_close($imap, CL_EXPUNGE);
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.