-1

I have a login form, and I want to be able to extract the domain name of the email address input then overwrite a pre-defined variable with a new one just read.

This is my code:

<form action="example.php" method="POST">
<input type="text" name="input_value"> //assume I input gooogle@gmail.com
<input type="hidden" name="isp" id="isp" value="unknown" />
<input type="submit" name="submit">

example.php:

<?php
$isp = $_POST["isp"];
//rest of code

?>

I want to be able to read the domain and convert the variable $isp to a pre-defined value I put in place e.g 'gmail.com' = 'gmail', hence $isp = 'gmail'.

symcbean
  • 47,736
  • 6
  • 59
  • 94
  • 3
    Possible duplicate of [get domain name from an E-mail address in php](https://stackoverflow.com/questions/18235954/get-domain-name-from-an-e-mail-address-in-php) – MarcosAM Jan 05 '19 at 02:42
  • "How do i get the "user" from email address only? Is there any easy way to get the value before @ ?" I don't think it's a duplicate that post is just a poorly titled question, although he can get his answer there. – Second2None Jan 05 '19 at 02:56
  • That is not even 50% close to a duplicate, did you even read my post and compare it to the other post? there are a lot of differences mate. – Williams Harold Jan 05 '19 at 03:04
  • Mate, the result will be the same that you are looking for. Just reverse the result...but ok, maybe is difficult...you right. – MarcosAM Jan 05 '19 at 03:20
  • I have a perfect answer for this question already, here: https://stackoverflow.com/questions/6850894/regex-split-email-address/36297137#36297137 – Brogan Jan 06 '19 at 01:44
  • 1
    Possible duplicate of [Regex split email address](https://stackoverflow.com/questions/6850894/regex-split-email-address) – Brogan Jan 06 '19 at 01:44

1 Answers1

-2

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';
Pinke Helga
  • 6,378
  • 2
  • 22
  • 42
  • cool answer its definitely doing what I need it to do but I want to be able to do it without having to install any dependencies – Williams Harold Jan 05 '19 at 22:06
  • @WilliamsHarold Updated again to encourage you to rely on `imap_rfc822_parse_adrlist` as far as possible. – Pinke Helga Jan 06 '19 at 13:10
  • It is definitely useful but I am making templates for multiple users and wouldn't have to start explaining how and why they have to install `imap_rfc822_parse_adrlist` – Williams Harold Jan 07 '19 at 02:13
  • @WilliamsHarold That's why there is the line `define('ALLOW_FALLBACK_EMAIL_CHECK', true);` It allows the fallback version without IMAP enabled. You can uncomment ist, however, the default should be to commented out transfering the responsibility to the end user. An installation can do such settings automatically on user choice. There is no really well implemented alternative in PHP. – Pinke Helga Jan 07 '19 at 03:39