• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 695
  • Last Modified:

Check if E-Mail exists

Is there a chance to check an email-adress with php? Not only if the domain exists by checking the mailservers, also checking if the recipient is real by testing the reply code from the mail server for the 550 (no recipient)?
0
SpinningKASi
Asked:
SpinningKASi
2 Solutions
 
lexxwernCommented:
<?php

     function verifyemail_validateemail($email)
     {
          if (!preg_match("/^([\w|\.|\-|_]+)@([\w||\-|_]+)\.([\w|\.|\-|_]+)$/i", $email))
               return false;
          return true;
     }
     function verifyemail_validatehost($email, $return_mxhost=0)
     {
          if (!verifyemail_validateemail($email))
               return false;
               list($local,$domain) = explode("@",$email,2);
               $mxhosts = array();
     
          if(!checkdnsrr($domain, "MX") || !getmxrr($domain, $mxhosts))
               return false;
     
          if ($return_mxhost)
               return $mxhosts;
         
          return true;
     }


     function verifyemail_validateexists($email)
     {
          $mxhosts = verifyemail_validatehost($email, true);
         
          if (!is_array($mxhosts))
               return false;

          $found = false;
          $localhost = verifyemail_localhost();

          $mxsize = sizeof($mxhosts);
          for($i=0; $i<$mxsize; $i++)    
          {
               $socket = fsockopen($mxhosts[$i], 25);

               if(!$socket) continue;

               $foo = fgets($socket, 4096);

               # 220 <domain> Service ready
               if(!preg_match("/^220/i", $foo))
               {
                    verifyemail_closesocket($socket);
                    continue;
               }

               fputs($socket, "HELO ".$localhost."\r\n");
               $foo = fgets($socket);
               while (preg_match("/^220/i", $foo))
                    $foo = fgets($socket, 4096);

               fputs($socket, "VRFY ".$email."\r\n");
               $foo = fgets($socket, 4096);

               # 250 Requested mail action okay, completed
               if(preg_match("/^250/i", $foo))
               {
                    $found = true;
                    verifyemail_closesocket($socket);
                    break;
               }

               # 550 Requested action not taken: mailbox unavailable [E.g., mailbox not found, no access]
               if(preg_match("/^550/i", $foo))
               {
                    verifyemail_closesocket($socket);
                    continue;
               }

               fputs($socket, "MAIL FROM: <".$email.">\r\n");
               $foo = fgets($socket, 4096);

               fputs($socket, "RCPT TO: <".$email.">\r\n");
               $foo = fgets($socket, 4096);

               # 250 Requested mail action okay, completed
               # 251 User not local; will forward to <forward-path>
               if(preg_match("/^[250|251]/i", $foo))
               {
                    $found = true;
                    verifyemail_closesocket($socket);

                    break;
               }
         
               verifyemail_closesocket($socket);
          }

          return $found;
     }


     function verifyemail_closesocket($socket)
     {
          fputs($socket, "QUIT\r\n");
          fclose($socket);
         
          return true;
     }
?>
0
 
SpinningKASiAuthor Commented:
Looks good, but the function "verifyemail_localhost()" could not be found :(

Maybe I´m too blind to see it... Which funtion I have to use to check the mail?
0
 
ZaytsevCommented:
You could also try this function (I do not remember where I found it):

<?php

/*
Originally
By: Jon S. Stevens jon@clearink.com
Copyright 1998 Jon S. Stevens, Clear Ink
This code has all the normal disclaimers.
It is free for any use, just keep the credits intact.

Enacements and modifications:

           By:  Shane Y. Gibson  shane@tuna.org
Organization:  The Unix Network Archives (http://www.tuna.org./)
         Date:  November 16th, 1998
      Changes:  Added **all** comments, as original code lacked them.
                Added some return codes to include a bit more description
                for useability.

I disclaim nothing...nor do I claim anything...but
it would be nice if you included this disclaimer...

*/

/*  This function takes in an email address (say 'shane@tuna.org')
*  and tests to see if it's a valid email address.
*
*  An array with the results is passed back to the caller.
*
*  Possible result codes for the array items are:
*
*  Item 0:  [true|false]        true for valid email address
*                    false for NON-valid email address
*
*  Item 1:  [SMTP Code]        if a valid MX mail server found, then
*                    fill this array in with failed SMTP
*                    reply codes
*
*  Item 2:  [true|false]        true for valid mail server found for
*                    host/domain
*                    false if no valid mail server found
*
*  Item 3:  [MX server]        if a valid MX host was found and
*                    connected to then fill in this item
*                    with the MX server hostname
*
*  EXAMPLE code for use is at the very end of this function.
*/

function validateEmail ( $email )
{
    // used for SMTP HELO argument
    global $SERVER_NAME;  

    // initialize our return array, populating with default values
    $return = array ( false, "", "", "" );

    // assign our user part and domain parts respectively to seperate             // variables
    list ( $user, $domain )  = split ( "@", $email, 2 );
     
    // split up the domain name into sub-parts
    $arr = explode ( ".", $domain );

    // figure out how many parts to the host/domain name portion there are
    $count = count ( $arr );

    // get our Top-Level Domain portion (i.e. foobar.org)
    $tld = $arr[$count - 2] . "." . $arr[$count - 1];

    // check that an MX record exists for Top-Level Domain, and if so
    // start our email address checking
    if ( checkdnsrr ( $tld, "MX" ) )
    {
        // Okay...valid dns reverse record; test that MX record for
        // host exists, and then fill the 'mxhosts' and 'weight'
        // arrays with the correct information
        //
        if ( getmxrr ( $tld, $mxhosts, $weight ) )
        {
            // sift through the 'mxhosts' connecting to each host
            for ( $i = 0; $i < count ( $mxhosts ); $i++ )
            {
                // open socket on port 25 to mxhosts, setting                         // returned file pointer to the variable 'fp'
                $fp = fsockopen ( $mxhosts[$i], 25 );

                // if the 'fp' was set, then goto work
                if ( $fp )
                {
                    // work variables
                    $s = 0;
                    $c = 0;
                    $out = "";
         
                    // set our created socket for 'fp' to      
                    // non-blocking mode
                    // so our fgets() calls will return
                    // right away
                    set_socket_blocking ( $fp, false );

                    // as long as our 'out' variable has a
                    // null value ("")
                    // keep looping (do) until we get
                    // something
                    //
                    do
                    {
                        // output of the stream assigned
                        // to 'out' variable
                        $out = fgets ( $fp, 2500 );

                        // if we get an "220" code (service ready code (i.e greeting))
                        // increment our work (code (c)) variable, and null
                        // out our output variable for a later loop test
                        //
                        if ( ereg ( "^220", $out ) )
                        {
                            $s = 0;
                            $out = "";
                            $c++;
                            $return[2] = true;
                            $return[3] = $mxhosts[$i];
                        }
                        // elseif c is greater than 0
                        // and 'out' is null (""),
                        // we got a code back from some
                        // server, and we've passed
                        // through this loop at least
                        // once
                        //
                        else if ( ( $c > 0 ) && ( $out == "" ) )
                        {  
                            $return[2] = true;
                            break;  
                        }

                        // else increment our 's'
                        // counter
                        else
                        { $s++;    }
                     
                        // and if 's' is 9999, break, to
                        // keep from looping
                        // infinetly
                        if ( $s == 9999 ) { break; }
                     
                    } while ( $out == "" );

                    // reset our file pointer to blocking
                    // mode, so we wait
                    // for communication to finish before
                    // moving on...
                    set_socket_blocking ( $fp, true );

                    // talk to the MX mail server,
                    // validating ourself (HELO)
                    fputs ( $fp, "HELO $SERVER_NAME\n" );

                    // get the mail servers reply, assign to
                    // 'output' (ignored)
                    $output = fgets ( $fp, 2000 );

                    // give a bogus "MAIL FROM:" header to
                    // the server
                    fputs ( $fp, "MAIL FROM: <info@" . $tld . ">\n" );

                    // get output again (ignored)
                    $output = fgets ( $fp, 2000 );

                    // give RCPT TO: header for the email
                    // address we are testing
                    fputs ( $fp, "RCPT TO: <$email>\n" );                

                    // get final output for validity testing
                    // (used)
                    $output = fgets ( $fp, 2000 );

                    // test the reply code from the mail
                    // server for the 250 (okay) code
                    if ( ereg ( "^250", $output ) )
                    {
                        // set our true/false(ness)
                        // array item for testing
                        $return[0] = true;
                    }
                    else
                    {
                        // otherwise, bogus address,
                        // fillin the 2nd array item
                        // with the mail servers reply
                        // code for user to test if they
                        // want
                        $return[0] = false;
                        $return[1] = $output;
                    }
                 
                    // tell the mail server we are done
                    // talking to it
                    fputs ( $fp, "QUIT\n" );

                    // close the file pointer
                    fclose( $fp );

                    // if we got a good value break,
                    // otherwise, we'll keep
                    // trying MX records until we get a good
                    // value, or we
                    // exhaust our possible MX servers
                    if ( $return[0] == true )
                    { break; }
                }
            }
        }
    } else {
    // No MX record appears for the specified Top-Level Domain; possibly
    // an invalid host/domain name was specified.
        $return[0] = false;
        $return[1] = "Invalid email address (bad domain name)";
        $return[2] = false;
    } // end if checkdnsrr()

    // return the array for the user to test against
    return $return;
}
?>

<?php
    // Here is an example chunk of code...  Normally, you'd call the
    // validate email with a form or some other method to provide
    // the input email address
    //
    //  NOTE:  You need to delete the /* and */ comment entries

/*  
// Minimal HTML code to test validateEmail() function.  Save this
// to a file to test...try different email addresses in the
// 'email_address' variable field to see how it behaves.
//
<html>
<head>
<tilte> Validate an email address. </title>
</head>

<body bgcolor="#000000" TEXT="#FFFFCC" LINK="#33CCFF" VLINK="#9999CC" ALINK="#FFFF00">

// Assumes that you put the validateEmail() function in a file
// named "validateEmail.php3", which is in the current directory
<?php  include( "validateEmail.php3" );

    $email_address = "shane@tuna.org";
    $val_results = array( "", "" );

    $val_results = validateEmail( $email_address );

    if ( $val_results[0] == true )
        {
            $value = "<font color=\"green\">a valid</font>";
        } else {
            $value = "<font color=\"red\">not a valid</font>";
        }

   // print debugging info
    print( "<br>Debugging Info:<br><br>" );
    print( "<pre>" );
    print( "(valid/not valid)                   <font color=\"white\">value</font> is: " . $value. "<br>");
    print( "(true/false valid email)   <font color=\"white\">val_results[0]</font> is: " . $val_results[0] . "<br>");
    print( "(SMTP code if false)       <font color=\"white\">val_results[1]</font> is: " . $val_results[1] . "<br>");
    print( "(true/false valid MX host) <font color=\"white\">val_results[2]</font> is: " . $val_results[2] . "<br>");
    print( "(MX host that answered)    <font color=\"white\">val_results[3]</font> is: " . $val_results[3] . "<br>");
    print( "</pre>" );
    print( "<pre>true is represented by a 1 (one)<br>false is represented by null output</pre><br>");
    // end debugging info

    print( "The address <font color=\"white\"><tt>" . $email_address . "</tt></font> is " . $value . " email address.");
*/
     
?>

</body>
</html>
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
tomcleggCommented:
Keep in mind that it is impossible to predict whether email to a given address will bounce.

Some MTAs (eg. qmail) do not check the user part of the address before acknowledging a RCPT.

All you're really checking in that case is whether the domain can accept incoming email at the moment.

You could also be fooled by a mail server that won't actually deliver anything, but will accept your RCPT (eg. disk full, misconfigured, malicious).

Some domains (spammers) set up MX pointing to 127.0.0.1.  If you're not careful you'll end up testing whether your local machine relays for itself.

Just some thoughts about how reliable you can expect this to be.  Of course, whether you actually care depends on your application...
0
 
Big_Red_DogCommented:
In addition to 127.0.0.1, check the email address itself to see if it is you or not.  Spammers love doing this too!
0
 
Big_Red_DogCommented:
Did any of this help you?  If so, please award a grade to close this question.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now