Einzelnen Beitrag anzeigen
Alt 13.07.2009, 16:52   #1 (permalink)
Atomic
Administrator 10 Jahre hx3
5000 Beiträge
 
Benutzerbild von Atomic
 
Registriert seit: 21.02.2003
Ort: Köln
Alter: 38
Beiträge: 5.162
Atomic eine Nachricht über Skype™ schicken
Standard PHP E-Mail-Validation mit IDN (Internationalized domain name) Support

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.
Angehängte Dateien
Dateityp: zip IDNA.php.zip (18,4 KB, 35x aufgerufen)
__________________
https://savetheinternet.info/
Atomic ist offline   Mit Zitat antworten