How to get email domains - php

DATABASE:
firstmail#gmail.com
secondmail#gmail.com
thirdmail#yahoo.com
fourthmail#hotmail.com
fifthmail#yahoo.com
QUESTION:
I made function that will take only email domain [gmail, yahoo, etc] but it saves in variable only last email domain, but i need it to save all domains in one variable but cant save 2 equal domains...
EXAMPLE:
In database:
firstmail#gmail.com
secondmail#gmail.com
thirdmail#yahoo.com
fourthmail#hotmail.com
fifthmail#yahoo.com
In variable:
gmail
yahoo
hotmail
CODE:
$subscriptions_emails = Subscription::select('email')->get()->toArray();
foreach ($subscriptions_emails as $domains){
$full_email = implode (',', $domains); // test#gmail.com
$email_split_dot= explode(".", $full_email); // 0 = test#gmail 1 = com
$email_without_after_dot = $email_split_dot[0]; // test#gmail
$email_split_at_symbol = explode("#", $email_without_after_dot); // 0 = test 1 = gmail
$email_domain = $email_split_at_symbol[1]; // gmail
}
dd($email_domain);

try to use an array to help collecting domain names like:
$domains = array();
foreach ($subscriptions_emails as $domains){
$full_email = implode (',', $domains);
$email_split_dot= explode(".", $full_email);
$email_without_after_dot = $email_split_dot[0];
$email_split_at_symbol = explode("#", $email_without_after_dot);
$email_domain = $email_split_at_symbol[1];
if(!in_array($email_domain, $domains, true)){ //check if not already exist
array_push($domains, $email_domain);
}
}
var_dump($domains);

You can use a regular expression also:
$email_domains = array();
foreach($emails as $email){
preg_match('/#([^.]+)\./', $email, $domain);
$email_domains[$domain[1]] = $domain[1];
}
Explanation of regex:
# look for an # followed by
([^.]+) look for one or more characters that arent
a point and put it in a subpattern followed by
\. look for a point

Related

Create Domain that have valid format and skip others

I am working on storing functionality of domains in laravel 5.3. Here user enter multiple domains in textarea one per line I want to validate each domain with right format should be create and other should be skipped and also count with correct format and bad format.
here is my code
$name = $request->input('domain_name');
$domains = preg_split('/[\r\n ,]+/', $name);
foreach ($domains as $domain) {
$data['domain'] = $domain;
$data['user_id'] = Auth::user()->id;
if (empty($request->input('domain_id'))) {
$domain = Domain::create($data);
}
}
Domain name with correct format should create and skip bad format and count both correct and incorrect formats.
Thanks for Help
Using preg_match and Regex:
if( ! preg_match("/^(?!-)(?:[a-zA-Zd-]{0,62}[a-zA-Zd].){1,126}(?!d+)[a-zA-Zd]{1,63}$/", $domain)) continue; // skip
or you can use this :
if(filter_var(gethostbyname($domain), FILTER_VALIDATE_IP))
{
return 'True';
}

Validate an email address in the URL

I will validate this URL with an email address inside.
These two domains are allowed:
https://www.example.com/secure/index.php?ID=john#example.com
https://www.example.com/secure/index.php?ID=john#example-test.com
All names before the # in the email address allowed.
When the user inserts another domain after the #, like this:
https://www.example.com/secure/index.php?ID=john#gmail.com
they will get an error. How can I do this?
Try this:
$email = $_GET['ID']; // remember to filter this!
$regex = '#\w+#(?<domain>\w+\-?\w+\.\w+)#';
preg_match($regex, $email, $matches);
$domain = $matches['domain'];
if ($domain !== 'example-test.com') {
// Unauthorised
}
See a working example here https://3v4l.org/SorhQ
See the regex and tweak if required here https://regex101.com/r/uDzOzm/1/
You can use the simple explode method to extract the domain name. see the code.
$parts = explode("#", "johndoe#domain.com");
$domain = $parts[1];
if(!in_array($domain, array('domain.com')))
{
//Redirect it wherever you want
}
You can do it:
if (isset($_GET['ID'])) {
$domain_name = substr(strrchr($_GET['ID'], "#"), 1);
if ($domain_name != "example-test.com"){
Forbidden....
}
}

Finding an exact match in a text file using PHP AJAX jQuery form

I have a .txt file where I would like to find an EXACT match of a single email entered in a form.
The present directives (see below) I used, work for a standard form. But when I use it in conjunction with an AJAX call and jQuery, it confirms it exists by just finding the first occurrence.
For example:
If that person enters "bobby#" it says not found, good.
If someone enters their full Email address and it exists in the file, it says "found", very good.
Now, if someone enters just "bobby", it says "found", not good.
I used the following three examples below with the same results.
if ( !preg_match("/\b{$email}\b/i", $emails )) {
echo "Sorry, not found";
}
and...
if ( !preg_match( "/(?:^|\W){$email}(?:\W|$)/", $emails )) {
echo "Sorry, not found";
}
and...
if ( !preg_match('/^'.$email.'$/', $emails )) {
echo "Sorry, not found";
}
my AJAX
$.ajax({
type: "POST",
url: "email_if_exist.php",
data: "email="+ usr,
success: function(msg){
my text file
Bobby Brown bobby#somewhere.com
Guy Slim guy#somewhere.com
Slim Jim slim#somewhere.com
I thought of using a jQuery function to only accept a full email address, but with no success partly because I didn't know where to put it in the script.
I've spent a lot of time in searching for a solution to this and I am now asking for some help.
Cheers.
Because your text file contains "bobby" in it, any regex such as you are suggesting will always find "bobby". I would suggest checking for the presence of the # symbol BEFORE you run the regex, as any valid email will always have # in it. Try something like this:
if (strpos($email,'#')) {
if ( !preg_match("/\b{$email}\b/i", $emails )) {
echo "Sorry, not found";
}
}
EDIT: Looking at this 4 years later... I would make the regex match to the end of the line, using the m modifier to specify multiline so the $ matches newline or EOF. The PHP line would be:
if ( !preg_match("/\b{$email}$/im", $emails )) {
If you're just checking to see if the user exists, this should work:
$users = trim(preg_replace('/\s\s+/', ' ', $users));
$userArray = explode(' ', $users);
$exists = in_array($email, $userArray);
Where $users is referencing to the example file and $email is referencing to the queried e-mail.
This replaces all newlines (and double spaces) with spaces and then splits by spaces into an array, then, if the e-mail exists in the array, the user exists.
Hope I helped!
'/^'.$email.'$/' is quite close. Since you want the check being "true" only if the full email address is on the file you should include in the pattern the "limits" of the email: Whitespace before and end_of_the_line after if:
'/ '.$email.'$/'
(Yes, I've just changed ^ -start of line- for a whitespace)
If your text file filled with lines that every line ending with the email,
so you can regex with testing and match by your "email + end od line"
like that:
if( preg_match("/.+{$email}[\n|\r\n|\r]/", $textFileEmails) )
{
/// code
}
The code would validate first using php core functions whether the email is correct or not and then check for the occurrence.
$email = 'bobby#somewhere.com';
$found = false;
//PHP has a built-in function to validate an email
if(filter_var($email, FILTER_VALIDATE_EMAIL)){
//Grab lines from the file
$lines = file('myfile.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
//Grab words from the line
$words = explode(" ", $line);
//If email found within the words set the flag as true.
if(in_array($email, $words)) {
$found = true;
//If the aim is only to find the email, we can break out here.
break;
}
}
}
if(false === $found) {
echo 'Not found!';
} else {
echo 'Found you!';
}
If you file is formatted as your example first_name, last_name, email#address.tdl
it's really easy to break it up on load to search.
I don't know why you would use preg_match for this bit your if you were advised to use preg use it to verify the email address. You're better off using indexOf method in php (strpos) to search the file but the below method works for your fixed file format.
Object Orientated File Reader and searcher
class Search{
private $users = array();
public function __construct($password_file){
$file = file_get_contents($password_file);
$lines = explode("\n", $file);
$users = array();
foreach($lines as $line){
$users = expode(" ", $line);
}
foreach($users as $user){
$this->users[] = array("first_name" => $user[0], "last_name" => $user[1], "email" => $user[2])
}
}
public function searchByEmail($email){
foreach($this->users as $key => $user){
if($user['email'] == $email){
// return user array
return $user;
// or you could return user id
//return $key;
}
}
return false;
}
}
Then to use
$search = new Search($passwdFile);
$user = $search->searchByEmail($_POST['email']);
echo ($user)? "found":"Sorry, not found";
Using preg_match to validate email then check
If you want to use preg and your own file search system.
function validateEmail($email) {
$v = "/[a-zA-Z0-9_-.+]+#[a-zA-Z0-9-]+.[a-zA-Z]+/";
return (bool)preg_match($v, $email);
}
then use like
if(validateEmail($_POST['email'])){
echo (strpos($_POST['email'], $emails) !== false)? "found":"Sorry, not found";
}

Check if a user entered an email address that has a domain similar to the domain name they enter above

In my signup form, I ask users to enter an email with the same domain name as they enter in the url field above.
Right now, I collect data this way:
URL : http://www.domain.com The domain.com part is what the user enters. The http://www is hard coded.
Email : info# domain.com The bold part is entered by the user. The # is hard coded.
The domain.com part in the url and domain.com part in the email should match. Right now, I can match the two fields since they are separate.
But I want to give up the above approach and make the user enter the entire domain name and email. When that's the case, what would be a good way to check if a user entered an email with the same domain he entered in the url field above.
I'm doing all this using php.
<?php
//extract domain from email
$email_domain_temp = explode("#", $_POST['email']);
$email_domain = $email_domain_temp[1];
//extract domain from url
$url_domain_temp = parse_url($_POST['url']);
$url_domain = strip_out_subdomain($url_domain_temp['host']);
//compare
if ($email_domain == $url_domain){
//match
}
function strip_out_subdomain($domain){
//do nothing if only 1 dot in $domain
if (substr_count($domain, ".") == 1){
return $domain;
}
$only_my_domain = preg_replace("/^(.*?)\.(.*)$/","$2",$domain);
return $only_my_domain;
}
So what this does is :
First, split the email string in 2 parts in an array. The second part is the domain.
Second, use the php built in function to parse the url, then extract the "host", while removing the (optionnal) subdomain.
Then compare.
you can do this by explode()
supp url = bla#gmail.com
$pieces = explode("#", $url);
$new = $pieces[1]; //which will be gmail.com
now again explode
$newpc= explode(".", $new );
$new1 = $newpc[0]; //which will be gmail
This is my version (tested, works):
<?php
$domain = 'www2.example.com'; // Set domain here
$email = 'info#example.com'; // Set email here
if(!preg_match('~^https?://.*$~i', $domain)) { // Does the URL start with http?
$domain = "http://$domain"; // No, prepend it with http://
}
if(filter_var($domain, FILTER_VALIDATE_URL)) { // Validate URL
$host = parse_url($domain, PHP_URL_HOST); // Parse the host, if it is an URL
if(substr_count($host, '.') > 1) { // Is there a subdomain?
$host = substr($host, -strrpos(strrev($host), '.')); // Get the host
}
if(strpos(strrev($email), strrev($host)) === 0) { // Does it match the end of the email?
echo 'Valid!'; // Valid
} else {
echo 'Does not match.'; // Invalid
}
} else {
echo 'Invalid domain!'; // Domain is invalid
}
?>
you could do:
$parsedUrl = parse_url($yourEnteredUrl);
$domainHost = str_replace("www.", "", $parsedUrl["host"]);
$emailDomain = array_pop(explode('#', $yourEnteredEmail));
if( $emailDomain == $domainHost ) {
//valid data
}
$email = 'myemail#example.com';
$site = 'http://example.com';
$emailDomain = ltrim( strstr($email, '#'), '#' );
// or automate it using array_map(). Syntax is correct only for >= PHP5.4
$cases = ['http://'.$emailDomain, 'https://'.$emailDomain, 'http://www.'.$emailDomain, 'https://www.'.$emailDomain];
$bSameDomain = in_array($site, $cases);
var_dump($bSameDomain);
Use regular expressions with positive lookbehinds(i.e only return the expression I'd like to match if it is preceded by a certain pattern, but don't include the lookbehind itself in the match), like so:
<?php
$url = preg_match("/(?<=http:\/\/www\.).*/",$_POST['url'],$url_match);
$email = preg_match("/(?<=#).*/",$_POST['email'],$email_match);
if ($url_match[0]==$email_match[0]) {
// Success Code
}
else {
// Failure Code
}
?>
Of course this is a bit oversimplified as you also need to account for https or www2 and the likes, but these require only minor changes to the RegExp, using the question mark as the "optional" operator

Find E-Mails with an exact e-mail address on an IMAP server using PHP

I want to connect to an IMAP-server and find all E-Mails that were sent to abc#server.tld. I tried:
$mbox = imap_open("{imap.server.tld/norsh}", "imap#server.tld", "5ecure3");
$result = imap_search($mbox, "TO \"abc#server.tld\"", SE_UID);
but this also listed e-Mails that were sent e.g. to 123abc#server.tld. Is it somehow possible to do a search for exact matches?
Short answer: you can't. I didn't find anything in RFC 2060 - Internet Message Access Protocol - Version 4rev1 saying that it can be done.
But, there is a workaround. First fetch all emails that contain abc#server.tld, then iterate through the results and select only the exact matches.
$searchEmail = "abc#server.tld";
$emails = imap_search($mbox, "TO $searchEmail");
$exactMatches = array();
foreach ($emails as $email) {
// get email headers
$info = imap_headerinfo($mbox, $email);
// fetch all emails in the TO: header
$toAddresses = array();
foreach ($info->to as $to) {
$toAddresses[] = $to->mailbox . '#' . $to->host;
}
// is there a match?
if (in_array($searchEmail, $toAddresses)) {
$exactMatches[] = $email;
}
}
Now you have all emails matching abc#server.tld in $exactMatches

Categories