Sending mail and validating an actual email? - php

I am sending users an activation link via php, I only have a regex in place to check if the email consists of *#*.* which is fine, but I would like to check if the email actually sends also.
I tried to do this with
if (mail(....)) {
// success
} else {
// error
}
But when I enter an email of a#a.a it still goes through to the success step.
How can I actually check if it is a correct email in php, thanks.

validate the email address preoperly with
if (filter_var($email_a, FILTER_VALIDATE_EMAIL)) {
echo "VALID";
}
the email server will return true on accepting the email it does not know if it will get to the user the only way to do this , and i'm sure you have seen it, is to get the recipient to click on a link in the email that sends them back to your site, then you know its valid\used address.

From the PHP docs
bool mail( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
Returns TRUE if the mail was successfully accepted for delivery, FALSE
otherwise.
It is important to note that just because the mail was accepted for
delivery, it does NOT mean the mail will actually reach the intended
destination.
Just because an email address is formatted properly does not mean that there is an actual mailbox at that location. There is no way in PHP to "check" if a email address exists/is active. That is the entire purpose of activation links, to verify that someone is checking that email address.

+1 for filter_var(). Use it instead of a simple regexp. Even the most complex regexp can't get every possible way of putting together an RFC 5322 compliant address. Your attempt to come up with something is pretty much guaranteed to fail.
But you didn't ask about address format verification, you asked about checking to see that the mail was sent. The whole purpose of an activation link is to validate the email address. If you clean up unvalidated accounts on a regular basis, it doesn't matter whether the email address is structured correctly. By sending a link, you're doing a full-circuit test that bypasses any possible format misinterpretations that filter_var() might have.

Related

PHP MySQL how pass value of variables into email body using placeholders

I am building an emailing template system using PHP. The idea is that the same system can be used to send a variety of automated email, eg when people join a site etc. The contents of each email are held on a MySQL database and I use placeholders to represent dynamic elements such as name, email, etc. The placeholders take the form of two underscores before and after a name: __name__, (NB the stackoverflow markup may convert the underscores to make the placeholder name appear in bold here) and a separate field matches the placeholder to the variable it represents eg:
__name__=[($user['name'])], __email=[($user['email'])]
When I construct the email, the system takes the placeholders and holds them in an associative array:
$placeholders( '__name__' => $user['name'], '__email__' => $user['email'] );
This is exactly how the array appears. I have used explode to strip out the enclosing [( and )] brackets.
I am able to loop through the email content and use Parsedown and preg_replace to swap the placeholders with their corresponding variables, eg:
$body = 'Dear __name__, your email is __email__'
becomes:
$body = 'Dear $user['name'], your email is $user['email']
However, this is exactly how the content appears in the final email that is actually sent. The value of these variables (which I have successfully established previously in an array $user ) do not appear in the final text, eg:
'Dear John, your email is john#smith.com'.
How do I get PHP to replace the variables with their values before the email is sent?
PS I have also tried:
'Dear ' . $user['name'] . 'Your email is ' . $user['email']
(ie with an inverted comma and a period to differentiate the variables from the rest of the text ) but no avail. It appears as:
Dear Mr Mercer,
Thank you for registering your details with mercermania.com.
Please verify your email address now
We now need to verify that the email address you supplied when you registered does indeed belong to you. Please click on the following link:
http://www.mercermania.com/activation/?x=' . $user_info['email'] . '&y=' . $user_info['active'] . '
I have done it before, so know it can be done but for the life of me I cannot remember how!
Any help greatly appreciated.
PS I am using PHP Mail::factory to send the email and an email is actually sent, and is received, so that is not the issue.

PHP, Validate if user entered an email domain, NOT address

I was looking for this answer, but I was not able to find this exact variation.
I'm looking for the following to validate:
#1) #toysrus.com
#2) #staples.com
#3) #example.com
And the following NOT to validate:
#1) staples.com
#2) Randy#staples.com
#3) #testcom
Basically, I want to force the user to enter a valid email domain, NOT an email address. Any clue how I could go about this?
I guess alternatively ask a user for their website domain name and just append the '#' character to that, but it's more confusing. It would be easier to simply to ask the user, please enter your company email domain name.
Thanks!
You can use the regular expression to match the email domain name.
For example:
$pattern = "^#(\w)+((\.\w+)+)$";
if (preg_match($pattern,$domain))
echo "Domain name right"
"^#" means the string should start with "#"."(\w)+" match at least 1 number or letter."(.\w+)+" match at least 1 domain name,such as ".com" or ".edu.cn". "$" means the end of the string.
This can be done in a multi-stage process
$email = 'something#somedomain.com';
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
// The email is a valid format so now we check the domain
$domain = explode('#', $email);
if(getmxrr($domain[1])) {
// This is about as far as we can take it.
// The email is valid and the domain has MX records
}
}

mail() php : without sender works, with sender doesn't works

I have a contact form, with mail() function.
For a long time it worked correctly. Suddenly now it doesn't work.
I have checked, but all is correct. But if I delete the sender parameter, it works, with sender parameters it doesn't work:
mail($destinatario_1,$oggetto_1,$messaggio_1,'');
WORKS
Instead:
mail($destinatario_1,$oggetto_1,$messaggio_1,'From: "My Name" <thisisanexample#gmail.com> \r\n');
Thanks
Try this instead:
mail($destinatario_1, $oggetto_1, $messaggio_1, "From: My Name <thisisanexample#gmail.com>");
Note that I leave our the \r\n which should just be \n on most servers and must be in double quotes not single quotes, and "My Name" shouldn't be in quotes.
Mail servers can be configured to not accept mail when certain information is set. The PHP mail() function more or less directly talks to the local mail server and passes the mail to it. Whether the mail server accepts it or not is not really part of the communication and cannot be detected by a PHP script.
Consult your web hosting company to find out if there are any restrictions.

Complete protection against mail-injection

Suppose we're sending trivial feedback and going to make these fields dynamic:
sender name
sender e-mail
subject
message body
would be this PHP code enough to protect us from all kinds of mail-injections?
//sanitizing email address
if ($email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
//encoding subj according to RFC and thus protecting it from all kinds of injections
$subject = "=?UTF-8?B?".base64_encode($_POST['subject'])."?=";
//encoding name for same reasons, and using sanitized email
$from = "From: =?UTF-8?B?".base64_encode($_POST['name'])."?= <$email>\r\n";
//protecting body as it mentioned in http://php.net/mail
$message = str_replace("\n.", "\n .", $_POST['text']);
mail('me#example.com',$subject,$message,$from);
}
at the moment I am playing with names like "some#email.com, other#email.com," but it seems that all available mail clients handling it correctly
would be this PHP code enough to protect us from all kinds of mail-injections?
It looks pretty comprehensive, just as long as your email client supports the RFC 2047 encoding method you're using in the headers. (Some webmail clients don't recognize the encoding.)
My only recommendation, other than not using mail() to begin with, would be considering is_email rather than the built-in filter. The built-in fails a number of edge cases.
It depends, if the filter complies with rfc that specify that the local part cant contain anything if it is surrounded by " or whatever character some address like "foo\r\nTo: poor-guy#dom.tld\r\nTo: dummy"#foo.tld will give you headers like :
Subject: foo
To: poor-guy#dom.tld
To: dummy"#foo.tld
quite bad ...

Zend Mail problem with foreign char + comma

Zend Mail throws an exception (because mail() returns false) when the to name is set to something with both a foreign character (like "å") and a comma (","). Re-produce with code below.
$mail = new Zend_Mail('utf-8');
$mail
->setFrom('info#myhost', 'My company')
->setSubject('hi')
->addTo('MYEMAIL#SOMEHOST.COM', 'aå,a')
->setBodyHtml('<p>asd</p>')
->send();
If I change the addTo call to something of the below, no error occurs.
->addTo('znarkus#gmail.com', 'aåa')
->addTo('znarkus#gmail.com', 'a,a')
->addTo('znarkus#gmail.com', 'aa')
The weird thing is, even though it throws an exception ("Unable to send mail"), the mail is delivered. I'm running the latest Zend Mail (1.9.5?). Please halp!
It's just a bug in Zend_Framework:
http://framework.zend.com/issues/browse/ZF-10792
a comma is allowed in the name part of the e-mail:
"Smith, Frank"
this is okay
The problem is that mail() function for $to accepts
User <user#example.com>, Another User <anotheruser#example.com>
and I guess that PHP internally splits the string on commas to separate multiple recipients but you are providing only one email address.
If you think this is a Zend_Mail, or PHP bug you should post this to the appropriate issue tracker.
The comma is a reserved literal in the "to" part of a mail header (and you should never use it though), separating different targets. Even if your "first" mail gets sent, imho it creates a header like this:
aå, a <znarkus#gmail.com>
With this header i assume your mta tries to send two mails: one to aå, which fails (badly), and a second one to znarkus#gmail.com, which should make its way.
You could try to look into the mail headers to confirm this theory.

Categories