home *** CD-ROM | disk | FTP | other *** search
Wrap
<?php /* validateEmail() by Shane Y. Gibson This is version validateEmail() augments the work that Jon Stevens originally wrote by (almost) fully documenting the code, and expands the $return array to include more (useful) information. An example chunk of code is also provided 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>