I'm upgrading to phpmailer 6 and testing my forms.
If I use the following code, it doesn't work:
$mail = new PHPMailer;
$mail->ContentType = 'text/plain';
$mail->IsHTML(false);
$mail->Sender = 'example#mydomain.com';
$mail->setFrom($_POST['email'], $_POST['name'], false);
$mail->addReplyTo($_POST['email'], $_POST['name']);
$mail->addAddress($to);
I have tried various combinations with setFrom (e.g. removing the boolean flag, omitting the $mail->Sender piece, omitting the addReplyTo) and it never works when using setFrom().
However, if I use this code, it does appear to work:
$mail = new PHPMailer;
$mail->ContentType = 'text/plain';
$mail->IsHTML(false);
$mail->From = $_POST['email'];
$mail->FromName = $_POST['name'];
$mail->addAddress($to);
Any idea why the setFrom() doesn't send the email?
You have not said what you mean by "doesn't work". Does it throw errors, not send at all, or what? It would help to see an SMTP transcript (set SMTPDebug = 2).
Problems aside, this is a bad idea:
$mail->setFrom($_POST['email'], $_POST['name'], false);
This is forgery, and will cause your messages to be rejected or spam-filtered because it will break DMARC alignment. Setting $mail->Sender = 'example#mydomain.com'; will help a bit as your envelope sender will be ok, but generally speaking don't do this as it's not going to help with deliverability.
One difference that setFrom() has over setting the From property directly is that it verifies the address immediately, and you can see the result - try this:
if (!$mail->setFrom($_POST['email'], $_POST['name'], false)) {
die('bad address');
}
If you give it a bad address, then sending will fail, whereas it may still be attempted if you have set the property directly - this may explain the difference you're seeing.
I would advise you to set it up this way, that is not forging either the from address or the envelope sender, but still making replies to form submissions go to the submitter:
setFrom('example#mydomain.com');
if (!$mail->addReplyTo($_POST['email'], $_POST['name'])) {
die('bad address');
}
Related
So i just received this error when trying to send an mail using PHPmailer from my site.
SMTP Error: The following recipients failed: XXXX
I tried to set $mail->SMTPAuth = true; to false but no result. And i tried to change the password for the mail account and update that in the sendmailfile.php but still the same.
It worked as intended two days ago, now i don't know why this is happening. Since there ain't any error code either i don't really know where to begin and since it did work..
Anyone who might know?
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->ContentType = 'text/html';
$mail->IsSMTP();
$mail->Host = "HOST.COM";
$mail->SMTPAuth = true;
$mail->Username = "MAIL_TO_SEND_FROM";
$mail->Password = "PASSWORD";
$mail->From = "MAIL_TO_SEND_FROM";
$mail->FromName = "NAME";
$mail->AddAddress($safeMail);
$mail->AddReplyTo("no-reply#example.COM", "No-reply");
$mail->WordWrap = 50;
$mail->IsHTML(true);
$sub = "SUBJECT";
mail->Subject = ($sub);
I've encountered the same problem. Managed too fix it when i commented the next row:
$mail->isSMTP();
Noticed you already found an answer, however maybe this will fix the problem for other people.
This does prevent using your external SMTP server as RozzA stated in the comments.
Maybe your class.phpmailer.php file is corrupt. Download the latest version from :
https://github.com/PHPMailer/PHPMailer
$mail->SMTPDebug = 1; // enables SMTP debug information (for testing)
// 1 = errors and messages
// 2 = messages only
It is a restriction from your SMTP server.
Sending e-mail messages is a vital part of the ever-growing Internet business. Sometimes, a large number of e-mails are required to be sent daily, even hourly. With this comes also the ever-increasing problem with the e-mail spam, and the countless number of junk messages users receive constantly.
The most common restrictions are:
150 e-mails per hour;
1500 e-mails per 24 hours;
50 recipients per message, where each recipient is counted as a separately sent e-mail message (e.g. if you have 50 recipients in a single message, this willcount as 50 sent messages);
One solution is to use a mailing list, then the restriction is 1500 e-mails for 24 hours. There's no restriction for the amount of emails sent per hour, i.e. you can send an email to a mailing list with up to 1500 recipients without a problem.
If you reach the hourly/daily limit you will get this error when trying to send further e-mails:
550 - Stop, you are sending too fast!
You will be able to send e-mails again, once the hour/day has passed.
Things you should know in order to avoid exceeding your limit:
The above e-mail restrictions are valid for the entire hosting account, and not for a single mailbox. This means, that if one of your mailboxes exceeds the allowed limit, you will not be able to send messages from any of your other e-mail accounts.
If, at any point you receive the afore-mentioned error message, it is highly recommended to stop all attempts to send messages from your mailboxes. If you continue trying, your messages will be left in a mail queue, which will have to clear first, before the server timer can reset and allow you to send e-mails again.
try inlcuding this
$mail->SMTPDebug = 1;
Just try to set SMTPAuth to false.
there is a slightly less probable problem.maybe this condition is caused by protection placed by your ISP.and you said it worked well two days ago.maybe that is the problem.try contacting your ISP.
or maybe its a problem with the recipients/senders email adresses
Here is some additional info about SMTP Auth
PLAIN (Uses Base64 encoding.)
LOGIN (Uses Base64 encoding.)
e.t.c - you can watch here http://en.wikipedia.org/wiki/SMTP_Authentication
For me solution was to set SMTPAuth to true for PHPMailer class
Please note in your lines i.e....
$mail->Username = "MAIL_TO_SEND_FROM";
$mail->Password = "PASSWORD";
$mail->From = "MAIL_TO_SEND_FROM";
Here at Line 1 and 3 you have to use same email address (You can't use different email address), this will work sure, I hope u r using different email address, (Email address must be same as username/password matching).
for Skip sending emails to invalid adresses; use try ... catch
$mail=new PHPMailer(true);
try {
$mail->CharSet = 'utf-8';
$mail->isSMTP();
$mail->isHTML(true);
$mail->Host = 'smtp.yourhost.com';
$mail->Port = 25;
$mail->SMTPAuth = false;
$mail->Username = 'xxxx';
$mail->Password = 'xxxx';
$mail->SMTPSecure = 'tls';
$mail->SMTPDebug = 0;
$mail->MailerDebug = false;
$mail->setFrom($absender, $name);
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->Body = $message_other_player;
}
$mail->send();
// echo 'Message has been sent';
} catch (Exception $e) {
// echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
PHPMailer - Skip sending emails to invalid adresses
So as the title implies
Im trying to send an email (one email) but the problem I'm facing is bizarre.
Whenever debug is turned on, email is sent only once.
But when debug is turned off, around 3 to 4 emails are sent at once.
NOTE: I'm using localhost not an actual server.
to diagnose the problem, I did the following:
1- used a md5 to generate random string in the "subject" to check whether email is sent with same contents or different. and the results were totally different. meaning, emails weren't duplicate but actually being sent couple of times.
2- opened the project in a browser with no extensions to make sure the problem wasn't in an extension loading my project page more than once. and the results were also similar to number 1, different "subject" also.
so, long story shot. i have no idea what causes this problem to happen. and why it only stop happening when debug is turned on.
NOTE: this is not my first time to use PHP mailer, but my first time to face this problem. I'm also using the latest version of PHP mailer (6.5.1)
Here is my entire code:
in PHP mailer file:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
require ABSPATH.'inc/phpmailer/script/src/PHPMailer.php';
require ABSPATH.'inc/phpmailer/script/src/Exception.php';
require ABSPATH.'inc/phpmailer/script/src/SMTP.php';
function SendEmail(){
$mail = new PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_OFF;
$mail->SMTPAuth = true;
$mail->SMTPSecure = 'ssl';
$mail->isSMTP();
$mail->Host = '*****';
$mail->SMTPAuth = true;
$mail->Username = '*****';
$mail->Password = '*****';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = 465;
$mail->SMTPAutoTLS = false;
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
$mail->ClearAllRecipients();
$mail->clearAttachments();
//Recipients
$mail->setFrom('*****', '******');
$mail->addAddress('*******', '*****');
$mail->addReplyTo('******', '******');
//Attachments
$mail->addAttachment(ABSPATH.'upload/dog.jpg', 'new.jpg');
//Content
$mail->isHTML(true);
$mail->Subject = md5(rand()); //This is how I'm checking whether it sends same email with same subject header or different ones. and it does send different ones
$mail->Body = 'This is the HTML message body <b>in bold!</b>'. md5(rand());
$mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
$mail->ContentType = 'text/html; charset=utf-8\r\n';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
}
and here is the file I'm using to call the function
<?PHP
// NO LOOP here
require_once(ABSPATH.'inc/phpmailer/phpmailer.php');
SendEmail();
As always, the first place to check is the docs.
Since you've already tried the random hash in the subject trick (well done on your logic!), you know that the problem is not that your script is sending more than one message, but that your script is being called repeatedly, and you should see evidence of that in your web server logs too. The usual reason for this is browser extensions which have a nasty habit of doing multiple submissions. Test that by using a clean browser with no extensions (e.g. use a browser you don't normally use, like Opera, Brave, or Chrome Canary).
Any requests that your browser is making should appear in the network tab of the dev console. On the server side you can either set up remote debugging to trigger breakpoints (tricky), or var_dump every request to a log so you get full details of what's calling the script.
BTW, you really shouldn't be disabling TLS verification. Fix the problem properly instead of hiding it; the troubleshooting guide has lots on that subject.
I had the same issue and solved by upgrading to the latest version of PHPMailer.
The announcement I am referring to was posted at:
http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html
I have used code like this in many websites:
$mail = new PHPMailer(true);
$mail->SetFrom('info#mysite.com', 'My Site');
$mail->AddReplyTo( $contact_email, "$contact_name" );
$mail->Subject = $subject;
$mail->AltBody = $mail_text;
$mail->MsgHTML($mail_html);
$result = $mail->Send();
Am I safe from the vulnerability because my from address is hard-coded? Should I worry about the reply-to address, which comes from user input? I do validate it with filter_var, but if I understand correctly, a from address can pass validation and still inject code because spaces are technically allowed in email addresses.
Yes, you are safe.
As Sammitch said, you should never use a user-supplied from address anyway because it will be forgery and you will fail SPF checks. This is mentioned in the PHPMailer docs and in many answers on SO.
i have a problem with my address validator in PHPMailer . can someone help me with a valid one ? my PHP version is 5.6.19 and PHPMailer's version is 5.2.16 so basically the library selected is pcre8 . puny Encode :
return (boolean)preg_match(
'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}#)' .
'((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
'(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
'([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
'(?2)")(?>(?1)\.(?1)(?4))*(?1)#(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
'(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
'|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
'|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
'|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
$address
);
send.php:
<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
require_once('class.phpmailer.php');
$to=isset($_POST['verify'])?$_POST['verify']:false;
$subject="Email verification";
$message='<p>Welcome to Our service this is an email verification procedure, Please click here to go back.';
//$to= "whoto#otherdomain.com";
$mail = new PHPMailer();
$mail->isSMTP(); // telling the class to use SMTP
// SMTP Configuration
$mail->SMTPSecure='ssl';
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "smtp.gmail.com "; // SMTP server
$mail->Username = "mymail#gmail.com";
$mail->Password = "mypassword";
$mail->Port = 465; // optional if you don't want to use the default
$mail->From = "<example#host.com>";
$mail->FromName = "Admin";
$mail->Subject = $subject;
//$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
$mail->isHTML(true);
$mail->Body=$message;
$mail->msgHTML($message);
$mail->addAddress($to);
if(!$mail->Send())
{
$response = "Message error!".$mail->ErrorInfo;
echo $response;
// echo $to;
}
else {
$response = "Message sent!";
echo $response;
}
?>
Thanks !
It's certainly true that in theory you can't validate email addresses exactly using regular expressions (as that famous question demonstrates), though that's mainly due to trying to accommodate the more complex (and mostly irrelevant in this context) requirements of RFC822, rather than the more practical and much simpler requirements of RFC821. In practice however, it works sufficiently well to be worthwhile. This is why, for example, the PHP filter_var function's FILTER_VALIDATE_EMAIL flag uses one (by the same author as the pcre8 pattern in PHPMailer).
I suspect you're running into a long-standing PHPMailer bug that's something do with PCRE in PHP - but it's inconsistent and doesn't affect everyone even when they have the same PHP and PCRE versions, so it's not been solved. The pcre8 pattern uses some features only available in later versions of PCRE, and the older, less-accurate pcre pattern does not use those features, and does not run into the same problem. You can tell PHPMailer to use that pattern for its internal validations by setting this class property:
PHPMailer::$validator = 'pcre';
Alternatively you can inject your own validator function by setting that same class property to a callable, for example this will make it consider all addresses valid:
PHPMailer::$validator = function($email) { return true; };
Update: It always helps to see your code! I see two problems:
$mail->From = "<example#host.com>";
That is not a valid From address, and is probably the cause of your error. You would get notification of this problem if you used setFrom() instead of setting From and FromName:
$mail->setFrom('example#host.com', 'Admin');
Secondly, your code should fail on PHPMailer 5.2.16 - you're not using the autoloader and not loading the SMTP class, so it will be unable to find the class and won't load it for you. It may be that your code is failing before it gets as far as trying to send, so you're not seeing that problem. I recommend using composer anyway.
I'm sending emails using a PHP script and class.phpmailer.php.
I need to be able to 'catch' bounces and auto-responses. I'm able to catch the bounces already. I created an alias that redirects bounces to a php script, and I parse the email there. I include some information in the original email in the headers, so I can know which emails bounced.
The same logic should work for the auto-responses, I think the problem is that the email are not getting to the server. I already have a reverse DNS configured, pointing to the server IP address.
This is part of how I send an email:
$mail = new PHPMailer();
$mail->From = $fromAddr;
$mail->Sender = $sender;
$mail->FromName = $fromName;
$mail->AddAddress($email);
$mail->IsHTML(true);
$mail->Subject = $subject;
the I add the headers, for example:
$mail->AddCustomHeader($mail->HeaderLine("From", $fromAddr));
$mail->AddCustomHeader($mail->HeaderLine("Subject", $subject));
$mail->AddCustomHeader($mail->HeaderLine("Company-State", "Florida"));
$mail->AddCustomHeader($mail->HeaderLine("Company-Country", "USA"));
$mail->AddCustomHeader($mail->HeaderLine("From", $fromAddr));
$mail->AddCustomHeader($mail->HeaderLine("Reply-To", $fromAddr));
My RDNS is something like: mail2.mydomain.com. The bounces are going to "www-data".
What should I add and where? something like www-data#mail2.mydomain.com?
Tks!