HX3 Foren

HX3 Foren (https://hx3.de/)
-   Software- und Webentwicklung (https://hx3.de/software-webentwicklung-23/)
-   -   PHP E-Mail-Validation mit IDN (Internationalized domain name) Support (https://hx3.de/software-webentwicklung-23/php-e-mail-validation-idn-internationalized-domain-name-support-17398/)

Atomic 13.07.2009 16:52

PHP E-Mail-Validation mit IDN (Internationalized domain name) Support
 
Liste der Anhänge anzeigen (Anzahl: 1)
Internationale Domain Namen (IDN) - Was ist das?
Seit 2004 dürfen *.de-Domains (und auch einige andere Top-Level-Domains) Umlaute (äöü...) enthalten.

Das Problem: Während man nun seit 5 Jahren solche Domain-Namen registrieren kann ist die Unterstützung in Web-Software (CMS, Services, Websites) katastrophal. Ich möchte hier einen kleinen Beitrag leisten.

Und zwar möchte ich erstens zeigen wie man mit IDN-Domains umgeht. Und zweitens möchte ich zeigen wie man E-Mail Adressen mit IDN-Domains validiert.

Was man über IDN-Domains wissen muss, ist folgendes:
IDN-Domains werden in Unicode DARGESTELLT.
Da man Unicode so schlecht verarbeiten kann gibt es eine Art "Codex", welcher den Domain-Namen so umschreibt, dass er nur noch ASCII-Zeichen enthält:

Aus http://süße.de wird xn--httpssse-b6a.de

Diese neue "Schreibweise" nennt sich Punycode.
( Punycode ? Wikipedia )

Den "Codex" um zwischen Punycode und Unicode hin und her zu übersetzen gibt es z.B. bei PEAR: Net_IDNA
Oder einfach im Anhang dieses Posts.
Für den folgenden Code ist es zwingend notwendig die Version im Anhang dieses Postes zu verwenden! (Klassennamen habe ich abgeändert.)

Die Validierungsfunktion habe ich von http://www.linuxjournal.com/article/9585 übernommen und erweitert mit IDN-Domains Support. Guter Artikel!

PHP-Code:

/*
 * Make sure you got the version from http://hx3.de/software-webentwicklung-23/php-e-mail-validation-idn-internationalized-domain-name-support-17398/
 */
include_once("IDNA.php");


/**
 * PHP Validation
 *
 * @author Douglas Lovell (http://www.linuxjournal.com/article/9585) Thanks!
 * @return string the error message if an error occures else return void
 */
 
function validate($email){
    
$email trim($email);
    
    
//Minimum lenght
    
$min_lenght=5;
    
    
//Maximimum lenght your database acceppts (VARCHAR(265))
    
$max_lenght=265;
    
    
$isValid true;
    
$atIndex strrpos($email"@");
    
    if(empty(
$email)){
        
        
$error="Field is empty";
        
    } else if (
$atIndex===null||$atIndex===false){
        
        
$isValid false;
    
    } else if(
strlen($email)<$min_lenght){
        
        
$error=$min_lenght." chars are required!";
        
    } else if(
strlen($email)>$max_lenght){
        
        
$error="Only ".$max_lenght." chars are allowed!";
        
    } else {
        
$domain substr($email$atIndex+1);
        
        if (
strrpos($domain' ')!==false) {
            
$error="EMail-Adress is not valid!";
        } else {
            
/*
             * Lets encode the domain-name to punycode
             */
            
$idna_converter = new convert_IDNA();
            
//try{
            
$domain $idna_converter->encode($domain);
            
//} catch(exception $e){
                //$isValid=false;
            //}
            
$local substr($email0$atIndex);
            
$localLen strlen($local);
            
$domainLen strlen($domain);
            if (
$localLen || $localLen 64){
                
// local part length exceeded
                
$isValid false;
            } else if (
$domainLen || $domainLen 255) {
                
// domain part length exceeded
                
$isValid false;
            } else if (
$local[0] == '.' || $local[$localLen-1] == '.') {
                
// local part starts or ends with '.'
                
$isValid false;
            } else if (
preg_match('/\\.\\./'$local)) {
                
// local part has two consecutive dots
                
$isValid false;
            } else if (!
preg_match('/^[A-Za-z0-9\\-\\.]+$/'$domain)) {
                
// character not valid in domain part
                
$isValid false;
            } else if (
preg_match('/\\.\\./'$domain)) {
                
// domain part has two consecutive dots
                
$isValid false;
            } else if (!
preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/'str_replace("\\\\","",$local))){
                
// character not valid in local part unless 
                // local part is quoted
                
if (!preg_match('/^"(\\\\"|[^"])+"$/'str_replace("\\\\","",$local))){
                    
$isValid false;
                }
            }
            if (
$isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))) {
                
// domain not found in DNS
                
$error="EMail-Adress seems to not exist!";
            } else if(!
$isValid){
                
$error="EMail-Adress is not valid!";
            }
        }
    }
    
    if(isset(
$error)) return $error;
    else return;
}


/**
 * Encode E-Mail to Punycode
 *
 * @param string  email-adress
 * @author Herbert Walde 
 * @see http://hx3.de/software-webentwicklung-23/php-e-mail-validation-idn-internationalized-domain-name-support-17398/
 * @return string punycode of email
 */
function encodeEMail($unicode_email){
    
$atIndex strrpos($unicode_email"@");
    
$domain encodeDomain(substr($unicode_email$atIndex+1));
    
$local substr($unicode_email0$atIndex);
    return 
$local."@".$domain;
}


/**
 * Decode E-Mail to Unicode
 *
 * @param string  email-adress
 * @author Herbert Walde
 * @see http://hx3.de/software-webentwicklung-23/php-e-mail-validation-idn-internationalized-domain-name-support-17398/
 * @return string email in unicode
 */
function decodeEMail($punycode_email){
    
$atIndex strrpos($punycode_email"@");
    
$domain decodeDomain(substr($punycode_email$atIndex+1));
    
$local substr($punycode_email0$atIndex);
    return 
$local."@".$domain;
}


/**
 * Encode IDN-Domain to Punycode
 *
 * @param string  domain
 * @author Herbert Walde
 * @see http://hx3.de/software-webentwicklung-23/php-e-mail-validation-idn-internationalized-domain-name-support-17398/
 * @return string domain in punycode 
 */
function encodeDomain($unicode_domain){
    
$idna_converter = new convert_IDNA();
    return 
$idna_converter->encode($unicode_domain);
}


/**
 * Decode Punycode-Domain to IDN-Domain
 *
 * @param string  domain
 * @author Herbert Walde
 * @see http://hx3.de/software-webentwicklung-23/php-e-mail-validation-idn-internationalized-domain-name-support-17398/
 * @return string domain in unicode
 */
function decodeDomain($punycode_domain){
    
$idna_converter = new convert_IDNA();
    return 
$idna_converter->decode($punycode_domain);
}


//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// BEISPIELE /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////


$email "  customer/department=shipping@süßes.com ";

$error validate($email);
if(isset(
$error)){
    echo 
"An error occured: ".$error;
} else {
    
//save $email to database:
    
$sql "INSERT INTO users (email) VALUES (\"".$pdo->quote($email)."\");";
    
$pdo->query($sql);
    
//.........
    
    //send email to user:
    
$punycode_email encodeDomain($email);
    
mail($punycode_email"Test Mail""Dies ist ein Test.");


Kleinere Bugs vorbehalten. (Ich musste den Code umschreiben.)

Der Quellcode von PEAR_IDNA steht unter der GPL.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 Uhr.

Angetrieben durch vBulletin, Entwicklung von Philipp Dörner & Tobias


SEO by vBSEO 3.2.0 ©2008, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119