[PHP] Walidacja e-mail a zdrowy rozsądek

0

Witam.

Napotkałem na pewien problem. Z mojego doświadczenia wynika, że często różne serwisy burzą się na prawidłowe, acz nietypowe adresy e-mail. Poczynając od tych w nowych TLD (.museum itp.), na różnych innych dziwnych kończąc. W związku z tym postanowiłem znaleźć coś rozsądnego. Jednak pojawił się problem polegający na znalezieniu złotego środka. Technicznie poprawny jest regexp który można znaleźć tutaj: http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html jednak, jak łatwo się domyśleć jest to dość wymyślny sposób na sprawdzanie poprawności (i dowód na to, że tak na prawdę, w głębi, RegExpy są trudne ;P). Trochę poszukiwań doprowadziło mnie do prostszych (aczkolwiek nie koniecznie do końca poprawnych) możliwości: http://mcv.jogger.pl/2007/06/25/validates-as-email/ http://www.regular-expressions.info/email.html oraz http://www.email-unlimited.com/stuff/email_address_validator.htm

Powstaje pytanie - co, jako autorzy serwisu internetowego, polecilibyście zastosować? Która z tych metod jest najlepsza, łącząca szybkość działania ze skutecznością? Przejrzystość kodu i takie tam właściwie mogę sobie darować, i tak wyląduje to w jakiejś funkcji w helperze, do której jak Bóg da nie będę musiał drugi raz zaglądać :) Czy warto stosować rozwiązanie teoretycznie idealne, ale jak sądzę po złożoności wyrażenia prawdopodobnie wolne, jakim jest http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html ?

P.S. Przy okazji, znacie może jakieś skuteczne funkcje do walidacji adresów JID?

0

To ja rzucam jeszcze jeden adres: http://fightingforalostcause.net/misc/2006/compare-email-regex.php. Możesz jeszcze pokombinować sprawdzając poszczególne fragmenty adresu lub ogólnie używając wielu wyrażeń regularnych, jak np. tu: http://www.ilovejackdaniels.com/php/email-address-validation/ Ale czy to aby na pewno szybsze rozwiązanie niż tamten kosmiczny regexp - nie mam pojęcia.

0

według mnie to głupota - ktoś będzie chciał wpisać trefny mail to wpisze, ja sprawdzam tylko czy jest małpa, czy przed małpą jest przynajmniej jeden znak, czy po małpie są przynajmniej 3 znaki, a w tym kropka

inne kombinacje są imo po pierwsze przekombinowane, po drugie - nie przyszłościowe, bo za n latek mogą się kryteria zmienić i będziesz musiał wyrażenie poprawiać, np: czy któreś z powyższych wyrażeń regularnych uzna polski znaczek diakrytyczny w domenie ?

moje sprawdzanie też jest bez sensu bo czy po małpie nie może być czasem IPv6 serwera mailowego ? :>

0

to zalezy do czego potrzebna ci jest walidacja. jezeli chcesz wyslac mejla do potwierdzenia rejestracji, to po co w ogole sprawdzac? najwyzej nie dojdzie, ale to juz nie twojka sprawa.

0
oksada napisał(a)

inne kombinacje są imo po pierwsze przekombinowane, po drugie - nie przyszłościowe, bo za n latek mogą się kryteria zmienić i będziesz musiał wyrażenie poprawiać, np: czy któreś z powyższych wyrażeń regularnych uzna polski znaczek diakrytyczny w domenie ?

Trzeba by przetestować, ale zakładając, że RFC-822 uznaje to za poprawny e-mail, to powyższe wyrażenie regularne też powinno. Nie oczekujcie ode mnie, że rozgryzę jak to działa i sprawdzę, jak już, to mogę wpisać jakiś adres pokroju ja@ósemka.pl i sprawdzić, co zwróci preg_match() :).
Standardy RFC tak często się nie zmieniają :]

oksada napisał(a)

moje sprawdzanie też jest bez sensu bo czy po małpie nie może być czasem IPv6 serwera mailowego ? :>

Może. I już widać, że ktoś, kto nie będzie miał nazwy domenowej dla swojego serwera mailowego, tylko będzie używał adresu IPv6, to nie wpisze u Ciebie swojego adresu :). Inną kwestią jest, czy ktoś taki adres by stosował w praktyce, ale jak ma jakiś ładny adres (pokroju 1:2:3:4:5:6), to właściwie czemu nie? :)

0

Ja czesto korzystam z tej funkcyjki ( juz nie pamietam skad ja zassalem):

function verifyEmail($email) {
      $wholeexp = '/^(.+?)@(([a-z0-9\.-]+?)\.[a-z]{2,5})$/i';
      $userexp = "/^[a-z0-9\~\!\#\$\%\&\(\)\-\_\+\=\[\]\;\:\'\"\,\.\/]+$/i";
      if (preg_match($wholeexp, $email, $regs)) {
          $username = $regs[1];
          $host = $regs[2];
          if (checkdnsrr($host, MX)) {
              if (preg_match($userexp, $username)) {
                  return true;
              } else {
                  return false;
              }
          } else {
              return false;
          }
      } else {
          return false;
      }
}
0

@maniek_2: Wyłoży się na .travel i .museum (całe szczęście przepuści .local)
(http://www.ktos.info/notatki/2007/02/07/poprawnosc-adresu-e-mail/ mi się przypomina ogólnie w tym temacie - ale i tamto rozwiązanie z CodeIgnitera nie jest najlepsze)

A co do walidacji JID to jedyne co możesz zrobić to sprawdzenie istnienia @ w podanym. Bo każdy inny warunek nie musi zachodzić.

0

Czy na prawdę każdy? Wszak po małpie chyba musi coś być, pewnie są też znaki, których nie wolno w JIDzie wpisywać... Chyba nie mam wyjścia tylko muszę pogrzebać w RFC i coś napisać samemu z prawdziwego zdarzenia :).

0

login nie jest chyba ograniczany co do znaków (no może co do niektórych, np @). A to co po @ musi spełniać warunki nazwy domeny ([a-z0-9-.]+).
// afair można użyć w loginie wszystkich znaków unikodowych poza @ właśnie - Ktos

0

Z tym po, to nie do końca - po nazwie domenowej może pojawić się / i potem zasób. I znów trzeba dojść, co w zasobie może występować - nie wiem, czy są jakieś ograniczenia. No i nazwa domenowa może być nazwą domenową, ale nie musi (może być jakaś nazwa lokalna zamiast FQDN, może być adres IP, może jeszcze coś innego? - tak jak w emailu).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.