Hlavní navigace

PHP okénko: Kontrola e-mailové adresy

Často po uživateli chceme, aby zadal svou e-mailovou adresu. Tuto adresu lze kontrolovat podle různých kritérií. Pro účely tohoto článku bude za e-mailovou adresu považován řetězec uživatel@doména, který obvykle chceme po uživateli zadat, a ne mnohem komplexnější řetězec, který lze zadat do hlaviček From, To a dalších.

Tweetni to Odměnte autora  Jak to funguje?

Syntaktická kontrola

V první řadě tu máme syntaktickou kontrolu. Na webu najdete spoustu pokusů, jak tuto kontrolu provádět, já sám jsem se na jedné podílel (příklad), ale dodatečně jsem v ní stejně našel chybu. Proto uvádím řešení, o kterém si aktuálně myslím, že je správné:

<?php
/** Kontrola e-mailové adresy
* @param string $email e-mailová adresa
* @return bool syntaktická správnost adresy
*/
function check_email($email)
{
    $atom = '[-a-z0-9!#$%&\'*+/=?^_`{|}~]'; // znaky tvořící uživatelské jméno
    $domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // jedna komponenta domény
    return eregi("^$atom+(\\.$atom+)*@($domain?\\.)+$domain\$", $email);
}
?> 

Ověření, zda adresa přijímá zprávy

Dále je možné kontrolovat, zda uvedená doména přijímá e-maily, což zjistí třeba funkce checkdnsrr. Podle RFC 2821 sice doména může poštu přijímat i bez MX záznamu, ale nebývá to zvykem.

Dále je možné server oťukat a zjistit, zda e-mail přijme. To je asi nejdůkladnější automatické řešení:

<?php
/** Ověření funkčnosti e-mailu
* @param string $email adresa příjemce
* @param string $from adresa odesílatele
* @return bool na adresu lze doručit zpráva, null pokud nejde ověřit
*/
function try_email($email, $from)
{
    if (!function_exists('getmxrr')) {
        return null;
    }
    $domain = preg_replace('~.*@~', '', $email);
    getmxrr($domain, $mxs);
    if (!in_array($domain, $mxs)) {
        $mxs[] = $domain;
    }
    $commands = array(
        "HELO " . preg_replace('~.*@~', '', $from),
        "MAIL FROM: <$from>",
        "RCPT TO: <$email>",
    );
    foreach ($mxs as $mx) {
        $fp = @fsockopen($mx, 25);
        if ($fp && substr($s = fgets($fp), 0, 3) == '220') {
            while ($s{3} == '-') {
                $s = fgets($fp);
            }
            foreach ($commands as $command) {
                fwrite($fp, "$command\r\n");
                if (substr($s = fgets($fp), 0, 3) != '250') {
                    return false;
                }
                while ($s{3} == '-') {
                    $s = fgets($fp);
                }
            }
            return true;
        }
    }
    return false;
}
?> 

Toto řešení ale pochopitelně nebude fungovat u serverů aplikujících greylisting.

Ověření, zda má uživatel adresu pod kontrolou

Pokud zároveň chceme ověřit, že má uživatel adresu pod kontrolou, musíme mu poslat zprávu:

<?php
/** Vygenerování náhodného řetězce
* @param int [$count] délka vráceného řetězce
* @param int [$chars] použité znaky: <=10 číslice, <=36 +malá písmena, <=62 +velká písmena
* @return string náhodný řetězec
*/
function rand_chars($count = 8, $chars = 36) {
    $return = "";
    for ($i=0; $i < $count; $i++) {
        $rand = rand(0, $chars - 1);
        $return .= chr($rand + ($rand < 10 ? ord('0') : ($rand < 36 ? ord('a') - 10 : ord('A') - 36)));
    }
    return $return;
}

$rand_chars = rand_chars();
if (mysql_query("INSERT INTO emaily (email, rand_chars) VALUES ('$_POST[email]', '$rand_chars')")) {
    $zprava = "Pokud máte zájem o služby serveru $_SERVER[SERVER_NAME], tak prosím navštivte tento odkaz:
http://$_SERVER[SERVER_NAME]/email_overit.php?id=" . mysql_insert_id() . "&rand_chars=$rand_chars
Pokud o služby serveru zájem nemáte, tak tuto zprávu prosím ignorujte.";
    $hlavicky = "MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit";
    mail($_POST["email"], "Overeni adresy", $zprava, $hlavicky);
}

// email_overit.php:
mysql_query("UPDATE emaily SET overeno = 1 WHERE id = '$_GET[id]' AND rand_chars = '$_GET[rand_chars]'");
?> 

Závěr

Záleží jen na vás, jak moc důkladně chcete kontrolu e-mailové adresy provádět. Nejčastěji se používají krajní varianty – buď pouhá syntaktická kontrola, nebo ověření, zda má uživatel adresu pod kontrolou.

Jakub Vrána

Jakub Vrána

Autor se živí programováním v PHP, podílí se na jeho oficiální dokumentaci, vyučuje ho na MFF UK a vede odborná školení. Poznámky si zapisuje na weblog PHP triky.

Ohodnoťte jako ve škole:
Průměrná známka 2,69
Tweetni to Odměnte autora  Jak to funguje?

TCP/IP síť na Linuxu I - dvoudenní workshop

 V dvoudenním workshopu se seznámíte se síťováním v Linuxu na všech vrstvách. Ujasníte si možnosti použití Linuxu v roli klienta, serveru i routeru.

Další informace o školení TCP/IP síť na Linuxu I - dvoudenní workshop»

       

Přehled názorů

Doplneni treti moznosti
LesTR 5. 5. 2006 00:29
Nový
├ 
Re: Doplneni treti moznosti
LesTR 5. 5. 2006 00:31
Nový
└ 
Re: Doplneni treti moznosti
Kalda 5. 5. 2006 11:33
Nový
Ke druhe moznosti
Michal Ludvig 5. 5. 2006 01:33
Nový
├ 
Re: Ke druhe moznosti
Mirek Topinka 5. 5. 2006 07:27
Nový
│
└ 
Re: Ke druhe moznosti
M jako Molitan 5. 5. 2006 13:44
Nový
│
 
└ 
Re: Ke druhe moznosti
Martin 8. 5. 2006 18:44
Nový
└ 
Re: Ke druhe moznosti
Jakub Vrána 5. 5. 2006 10:11
Nový
druha moznost + dalsi moznost
Lampa 5. 5. 2006 07:48
Nový
└ 
Re: druha moznost + dalsi moznost
Jakub Vrána 5. 5. 2006 10:28
Nový
 
└ 
Re: druha moznost + dalsi moznost
Lampa 5. 5. 2006 10:42
Nový
 
 
└ 
Re: druha moznost + dalsi moznost
Jakub Vrána 5. 5. 2006 10:47
Nový
 
 
 
└ 
Re: druha moznost + dalsi moznost
Lampa 5. 5. 2006 12:01
Nový
 
 
 
 
└ 
Re: druha moznost + dalsi moznost
anonymní uživatel 5. 5. 2006 12:30
Nový
vsechno spatne
J 5. 5. 2006 10:30
Nový
└ 
Re: vsechno spatne
Jakub Vrána 5. 5. 2006 10:42
Nový
 
├ 
Re: vsechno spatne
Kalda 5. 5. 2006 11:41
Nový
 
└ 
Re: vsechno spatne
anonymní uživatel 5. 5. 2006 11:58
Nový
 
 
└ 
Re: vsechno spatne
Michal Ludvig 6. 5. 2006 02:11
Nový
Ke druhému rešení
Kalda 5. 5. 2006 11:00
Nový
regex
zet 5. 5. 2006 11:30
Nový
└ 
Re: regex
Jakub Vrána 5. 5. 2006 11:51
Nový
 
└ 
Re: regex
Martin Mareš 5. 5. 2006 20:16
Nový
navrh na dalsi PHP okenko ...
ooohhhmmm 5. 5. 2006 14:37
Nový
ne zcela spravne
Bilbo 6. 5. 2006 13:34
Nový
└ 
Re: ne zcela spravne
. 1. 6. 2008 01:16
Nový
Re: PHP okénko: Kontrola e-mailové adresy
Neviem 26. 12. 2011 23:46
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem