note 119277 added to function.filter-var

From: Date: Mon, 02 May 2016 12:19:42 +0000
Subject: note 119277 added to function.filter-var
Groups: php.notes 
Request: Send a blank email to php-notes+get-205413@lists.php.net to get a copy of this message
Many people, myself included, have found that the FILTER_VALIDATE_EMAIL does not actually properly work. Below is a wrapper that I believe validates every legal routable address. <?php /******************************************* * * These are the function * * check_username is called by check_email * - it compensates for bugs in the php * filter_var function. * - returns boolean * * check_email is the function to use. * First argument is string, address to * check * Second argument is optional boolean, * whether or not to use DNS to validate * the domain name. Defaults to true * Returns boolean * */ function check_username($uname) { //Only UTF-8 addresses are legal if (iconv('UTF-8', 'UTF-8', $input) != $input) { return FALSE; } //replace all characters above U+007F with letter U for simplicity of checking $uname = preg_replace('/[\x{007F}-\x{FFFF}]/u', 'U', $uname); //remove comments - only legal in format (comment) at beginning or end of username $s[] = '/^\([^\)]*\)/'; $s[] = '/\([^\)]*\)$/'; $uname = preg_replace($s, '', $uname); //make sure we have something left if(strlen(trim($uname)) == 0) { return FALSE; } // check for legal dot usage if(substr_count($uname, '..') > 0) { return FALSE; } // convert \\ and \" to an A for simplicity $s[] = '/[\\\][\\\]/'; $s[] = '/\\\"/'; $uname = preg_replace($s, 'A', $uname); // check for illegal use of quotes if(preg_match('/[^.]+"[^.]+/', $uname)) { return FALSE; } // compensate for characters legal when in quotes $uname = preg_replace_callback('/"(.*)"/', function ($m) { $s[]="/[ \(\),\:;<>@\[\] ]/"; return preg_replace($s,'Q',$m[1]); }, $uname); // check what we have left with filter_var return filter_var($uname . '@example.org', FILTER_VALIDATE_EMAIL); } function check_email($email, $dns_check=true) { $array = explode('@', $email); if(count($array) < 2) { return FALSE; } $domain = end($array); array_pop($array); if(function_exists('idn_to_ascii')) { //php filter no workie with unicode characters $domain = idn_to_ascii($domain); } $ipcheck = preg_replace(array('/^\[ipv6\:/i', '/^\[/', '/\]$/'), '', $domain); if(filter_var($ipcheck, FILTER_VALIDATE_IP)) { // it's an IP address if(! filter_var($ipcheck, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { return FALSE; } } else { // it's a domain name // php bug - FILTER_VALIDATE_EMAIL doesn't like naked TLD if(! filter_var('user@a.' . $domain, FILTER_VALIDATE_EMAIL)) { return FALSE; } if($dns_check) { if(! dns_get_record($domain)) { return FALSE; } } } //now check legal username return check_username(implode('@', $array)); } ?> It evaluates the address in two parts, first evaluating the host and if that legal it then evaluates the user name. If there is a DNS problem *and* the default $dns_check value of true is used, valid will fail. If it is an international domain name, you have to have the php-intl package installed. Enjoy. ---- Server IP: 72.52.91.14 Probable Submitter: 71.9.134.226 ---- Manual Page -- http://php.net/manual/en/function.filter-var.php Edit -- https://master.php.net/note/edit/119277 Del: integrated -- https://master.php.net/note/delete/119277/integrated Del: useless -- https://master.php.net/note/delete/119277/useless Del: bad code -- https://master.php.net/note/delete/119277/bad+code Del: spam -- https://master.php.net/note/delete/119277/spam Del: non-english -- https://master.php.net/note/delete/119277/non-english Del: in docs -- https://master.php.net/note/delete/119277/in+docs Del: other reasons-- https://master.php.net/note/delete/119277 Reject -- https://master.php.net/note/reject/119277 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#205413) next »