Der kleine aber feine Unterschied zwischen is_email() und sanitize_email()

Wer mit E-Mails in WordPress arbeitet, sollte den Unterschied zwischen is_email() und sanitize_email() kennen. Er ist zwar klein, aber fein.

Der offensichtlichste Unterschied ist erst einmal der Rückgabewert. is_email() prüft ob eine gegebene E-Mail Adresse überhaupt den Kriterien entspricht und gibt einen String zurück wenn dem so ist. Andernfalls gibt is_email() false zurück. sanitize_email() hingegen gibt entweder einen String mit einer gültigen E-Mail Adresse oder einen leeren String zurück.
is_email() gibt also einen boolschen Wert oder einen String, sanitize_email() immer einen String zurück.

Nun könnte man mit einer einfachen Typumwandlung is_email() dazu bringen ebenfalls immer einen String zurück zu geben. (string) is_email( $email ) würde sich nahezu gleich verhalten wie sanitize_email(). Im Erfolgsfall eine gültige E-Mail Adresse, im Fehlerfall einen leeren String. Stimmt das? Überprüfen wir es:

$emails = array( 'foo@bar.com', 'baz-at-example-org', 'öttö@wördpäss.com', 'meh@cöm.com' );
echo '<ol>';
array_walk(
	$emails,
	function ($email) {
		$empty = 'an empty string';
		$is = (string) is_email( $email );
		$se = sanitize_email( $email );

		printf(
			'<li>%s - %s (%s)</li>',
			( '' != $is ) ? $is : $empty,
			( '' != $se ) ? $se : $empty,
             $email
		);
	}
);
echo '</ol>';

Die Ausgabe sieht in etwa so aus:

  1. foo@bar.com – foo@bar.com (foo@bar.com)
  2. an empty string – an empty string (baz-at-example-org)
  3. an empty string – tt@wrdpss.com (öttö@wördpäss.com)
  4. an empty string – meh@cm.com (meh@cöm.com)

Wie man sehen kann, gibt (string) is_email( $email ) wie erwartet bei ungültigen E-Mail Adressen einen leeren String zurück. Das WordPress glaubt das Umlaute in E-Mail Adressen nicht erlaubt seien, lass wir an dieser Stelle mal dahingestellt. WordPress kann halt (noch) nicht mit Umlautdomains umgehen.
Viel interessanter ist die Ausgabe von sanitize_email(). Auch sanitize_email() kann nicht mit Umlauten umgehen, streicht sie aber einfach aus der E-Mail Adresse anstatt sie z.B. zu kodieren.

Das führt nun natürlich zu Problemen wenn man es nicht weiß. Sollte mal eine größere Anzahl an E-Mails nicht versendet werden, kann das mitunter daran liegen das man vergessen hat vor dem Speichern zu prüfen ob WordPress damit umgehen kann.

// FALSCH
$user = array(
  'name' => 'Hans'
  'email' => sanitize_email( $email )
);
update_option( 'awesome_options', $user );

// Richtig
$user = array(
  'name' => 'Hans'
  'email' => sanitize_email( (is_email( $email ) )
);
update_option( 'awesome_options', $user );

Merke!

Jede E-Mail Adresse sollte bevor sie mit sanitize_email() verarbeitet wird erst mit is_email() validiert werden. Ansonsten bekommt man E-Mail Adressen die vielleicht lustig aussehen, es aber definitiv nicht sind.