You really should rely on imap_rfc822_parse_adrlist
from the php-imap module which uses the c-client
API. It processes a comma-seperated list and returns an array of objects and allows the format User <user@example.com
. With some additional logic you can fit it to your needs.
You stated in comments that you do not want to rely on installation dependencies. I strongly recommend to do so, even if there is a filter_var
function providing an email filter as well. It is not well implemented, producing false negatives. I would even not rely on it hoping it does not produce false positives.
E.g. RFC 822 allows quoted strings to appear in the mailbox part. Both, imap_rfc822_parse_adrlist
and filter_var
, consider "abc.def@ghi.jkl"@example.com
and abc."def@ghi".jkl@example.com
to be valid. However, abc.def"@"ghi.jkl@example.com
is according to the RFC 882 specs valid as well but a false negative of filter_var
. There are issues with IDN domains as well and probably many more.
Implementing a full RFC 822 compliant regex or algorithm in PHP is a very hard and error-prone task. Even simple email formats should not be validated by regex or similar since this will become a root of bugs or even serious security issues in larger projects some day.
I can provide you some fallback relying on filter_var. Again, I strongly recommend not to enable it by default. You can deliver it with a warning to enable it on the own risk.
<?php declare (strict_types=1);
// This should NOT be enabled. If possible, ensure to have installed the php-imap module.
//
// define('ALLOW_FALLBACK_EMAIL_CHECK', true);
if(function_exists('imap_rfc822_parse_adrlist'))
{
/**
* Get the host part (domain) of an email address.
*
* @param string|null $email email address, can be null
* @return string|null host part of the email address if the address is valid, otherwise NULL
*/
function get_host_from_email_addr(?string $email) : ?string
{
if(null === $email)
return null;
@[$obj, $obj2] = imap_rfc822_parse_adrlist($email, '');
imap_errors(); // flush errors, otherwise unsuppressable notifications on wrong format are shown due to external calls
// we want to allow 'simple email addresses' only and therefore exact the 2 properties:
// ->mailbox and ->host
return (isset($obj->mailbox, $obj->host) && !isset($obj2) && 2 === count(get_object_vars($obj)))
? $obj->host ?: null
: null
;
}
}
else if(defined('ALLOW_FALLBACK_EMAIL_CHECK') && ALLOW_FALLBACK_EMAIL_CHECK)
{
function get_host_from_email_addr(?string $email) : ?string
{
// This probably ensures getting a valid host name from email address.
// However, filter_var works too restrictive generating false negatives.
return filter_var($email, FILTER_VALIDATE_EMAIL, FILTER_FLAG_EMAIL_UNICODE) ? array_slice(explode('@', $email), -1)[0] : null ;
}
}
else
throw new Error('Unresolved dependency: Please install php-imap module or set constant ALLOW_FALLBACK_EMAIL_CHECK to TRUE.');
$isp_names =
[
'gmail.com' => 'Gmail',
'outlook.com' => 'Outlook',
];
$isp = @$_GET['isp'] ?: $isp_names[get_host_from_email_addr(@$_GET['input_value'])] ?? 'unknown';