Hay I'm using PHPMailer to send some simple emails, however the function SetFrom() doesn't seem to work, even though the code I'm using is straight from phpmails docs (http://phpmailer.worxware.com/index.php?pg=examplebmail)
Here my error
Call to undefined method PHPMailer::SetFrom()
and my script
require_once('inc/phpmailer/class.phpmailer.php');
$mail = new PHPMailer(); // defaults to using php "mail()"
$body = $message;
$mail->SetFrom('tell-a-friend#domain.com', 'tell a friend');
$mail->AddAddress($to_email, $to);
$mail->Subject = "tell a friend";
$mail->MsgHTML($body);
$mail->Send();
Any ideas?
EDIT
turns out the SetFrom() function doesnt exist in my version of phpmailer, i can set these values using
$mail->From = '';
$mail->FromName = '';
Careful, there are multiple versions of PHPMailer around. I've never quite understood which is which. Anyway, this download of PHPMailer 5.1 definitely contains a setFrom method:
public function SetFrom($address, $name = '',$auto=1) {
I concur with Pekka; I downloaded PHPMailer from here, used your code as-is (well, I assigned the $to_email, $to and $message variables) and the submission was successful.
Try using the version Pekka suggested, or this one, and hopefully your problem will go away.
Related
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');
}
Everything else is OK, but I can't send email for some reason:
<?php
$msg="";
use PHPMailer\PHPMailer\PHPMailer;
include_once "PHPMailer/PHPMailer.php";
include_once "PHPMailer/Exception.php";
if(isset($_POST['submit'])) {
$subject=$_POST['subject'];
$email=$_POST['email'];
$message=$_POST['message'];
$mail= new PHPMailer();
$mail->AddAddress('nkhlpatil647#gmail.com', 'First Name');
$mail->SetFrom('nkhlpatil647#gmail.com','admin');
$mail->Subject = $subject;
$mail-> isHTML(true);
$mail->Body=$message;
if($mail->send())
$msg="Your rmail msg has been send";
else
$msg="mail msg has not been send";
}
?>
The $mail->send() function always goes to the else part. What am I doing wrong?
You are not declaring what is sending the mail, that could be one reason. PHPMailer does not actually send e-mail, it is designed to hook into something on your web server that can send email, eg: sendmail, postfix, an SMTP connection to a mail relay service, etc., so you may need to declare that in your settings.
For example, if you are using your webserver built-in sendmail, add this after
$mail = new PHPMailer;
// declare what mail function you are using
$mail->isSendmail();
PHPMailer supports several other options as well, like SMTP, and gmail. See this set of examples to suit your scenario best: https://github.com/PHPMailer/PHPMailer/tree/master/examples
Also, here is how I have mine setup, not sure if require or include_once is optimal, but my installation works great. Also, I have SMTP module added for using that over sendmail.
// require php mailer classes
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
// require php mailer scripts
require 'src/Exception.php';
require 'src/PHPMailer.php';
require 'src/SMTP.php';
This is how my personal installatoin of PHPMailer works in practice, instantiated through PHP and NOT installed via Composer. I used this answer from another post on SO - How to use PHPMailer without composer?
I believe that it is good coding practice to use curly braces all the time. This is in reference to your if/else statement.
Other than that, I do not see anything in your code that jumps right out and says problem area.
Please make sure that all of your $_POST variables are echoing out their expected values.
Echo you message out as well to make sure it is outputting your expected values.
You do not want any of those parameters to be empty.
The PHPMailer class has error handling. I suggest that you use a try/catch block to show any possible errors that are present and trouble shoot from there.
You can also use $mail->ErrorInfo;. This will show any errors that were generated after the $mail->send() function call. I have included both concepts in my answer.
Like so:
$msg="";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception; //<---Add this.
//Switch your includes to requires.
require "PHPMailer/PHPMailer.php";
require "PHPMailer/Exception.php";
//require "PHPMailer/SMTP.php"; //If you are using SMTP make sure you have this line.
if(isset($_POST['submit'])) {
try{
$subject =$_POST['subject'];
$email =$_POST['email'];
$message =$_POST['message'];
//$mail = new PHPMailer();
$mail = new PHPMailer(true); //Set to true. Will allow exceptions to be passed.
$mail->AddAddress('nkhlpatil647#gmail.com', 'First Name');
$mail->SetFrom('nkhlpatil647#gmail.com','admin');
$mail->Subject = $subject;
$mail->isHTML(true);
$mail->Body = $message;
if($mail->send()){
$msg="Your email msg has been send";
}else{
$msg="mail msg has not been send";
echo 'Mailer Error: ' . $mail->ErrorInfo;
}
}catch(phpmailerException $e){
echo $e->errorMessage();
}
}
If you are using SMTP you can try playing with the $mail->SMTPDebug settings. May provide you with some additional information. Check the PHPMailer docs for the values and their properties.
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 using PHPMailer for a while now and never really had any problems, but last week I installed one of my CMS on a website and the client insisted on having 2 e-mails receiving the contents of the contact form of his website.
Ok, no problem I thought, just adding an e-mail address using the $phpmailer->AddAddress() function. However, adding a second receiver is causing PHPMailer to send the mail twice to both receivers. I tried adding a third receiver to see if I got it three times, but this didn't change anything. So adding 2+ receivers is causing PHPMailer to send the message twice to all receivers.
There's nothing strange in my code. It's a basic PHPMailer example:
$mail = new PHPMailer();
$mail->AddReplyTo("name#yourdomain.com","First Last");
$mail->SetFrom('name#yourdomain.com', 'First Last');
$mail->AddAddress("info#address.com");
$mail->AddAddress("info#address.nl");
$mail->Subject = "PHPMailer Test Subject via mail(), basic";
$mail->Send();
I've ran out of options. I have absolutely no clue where it's going wrong.
Thanks in advance
--
Just some random thought: I noticed the mailer is defaulted by iso-8859-1 and my site is running utf8. Can there be a "silent" redirect by the server itself?
//EDIT, that ^^ solved my problem
//EDIT2:
Ok, it did not.. today the script worked fine (just 1 mail with 2 receivers) but a moment ago the strange behavior started again. Any tips?
// Solution:
ok, I feel quiet stupid! The answer Zulkhaery Basrul came closest to the actual problem! This is what happened: I was sending an e-mail to multiple addresses in the "to" field. For example:
To: A, B, C
Both A/B are my own adresses. In outlook I had some message rules to put e-mails with certain addressees inside a specific folder. Both A and B had this rule.
When I recieved my e-mail, both mails contained both mailaddresses in the to-field. Causing both of the mails to meet the rule requirements for both rules. Thus keeping the original in one folder and creating a copy in the other (twice).
Thanks for thinking tho :)
You can use $SingleTo property.
From PHPMailer docs:
$SingleTo
Provides the ability to have the TO field process individual emails,
instead of sending to entire 'TO addresses'
$mail = new PHPMailer();
$mail->SingleTo = true; //will send mail to each email address individually
$mail->AddReplyTo("name#yourdomain.com","First Last");
$mail->SetFrom('name#yourdomain.com', 'First Last');
$mail->AddAddress("info#address.com");
$mail->AddAddress("info#address.nl");
$mail->Subject = "PHPMailer Test Subject via mail(), basic";
$mail->Send();
Try to add after
$mail->send();
$mail->ClearAddresses();
Ok, if someone runs into this problem like I did:
My website runs in utf-8, PHPMailer uses iso-8859-1 by default. Somehow the script is run in both charsets causing duplicates. Changing the charset in the class.phpmailer.php file to utf-8 solved the problem!
I think these will do the job :)
$mail->SingleTo = true;
$mail->CharSet = "UTF-8";
I tried everything, UTF8 / BOM check on all files, SingleTo-property, CharSet-property.
It didn't work.
I used the "View Details" function from Gmail and saw that my duplicate mails were sent without a subject.
So, I ended up with a very, very dirty fix.
I put this DIRECTLY below the first line of the send function in the class file:
public function Send() {
if ($this->Subject == "") {
return true;
}
// ... rest of code...
}
I ran into the same problem. The one and only right answer is $mail->ClearAllRecipients()
When I used the accepted answer BCC mails were being sent to all recipients.
SingleTo Is not a good idea. It only works with "sendmail" or "mail" transports, not with SMTP. If you use SingleTo with SMTP, this parameter is just ignored without any error or warning, and you may get duplicates.
According to the authors of the library, SingleTo is planned to be deprecated in the release of PHPMailer 6.0, and removed in 7.0. The authors have explained that it's better to control sending to multiple recipients at a higher level: "PHPMailer isn't a mailing list sender". They tell that the use of the PHP mail() function needs to be discouraged because it's extremely difficult to use safely; SMTP is faster, safer, and gives more control and feedback.
But SMTP is incompatible with SingleTo -- that's why the authors of PHPMailer will remove SingleTo, not SMTP.
I've used two PHP email scripts and routing it through my SMTP server, when I do this though it sends two of the same email.
When I use mail() this doesn't happen, but I'd much rather use SMTP.
Any ideas why this may be occuring?
If you're setting the 'To' and/or 'Recipient' header multiple times, the SMTP server could interpret that as separate e-mail address, thus you'll receive the multiple e-mails.
I'd recommend using the PEAR Mail class. Very simple to use, and handles much of the work for you. It supports multiple backends including SMTP. Likewise, if you want to expand your class to send HTML emails, the Mail_Mime class handles this very nicely, providing methods to set the plain-text body and the HTML body (in case the recipient doesn't support HTML).
So if you're only using PHPMailer without editing it's code, it's not your script's fault. Maybe check your SMTP server's configuration?
function send_email($from, $fromname, $to, $subject, $body, $alt = '')
{
require_once('class.phpmailer.php');
//include("class.smtp.php"); // optional, gets called from within class.phpmailer.php if not already loaded
$mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch
$mail->IsSMTP(); // telling the class to use SMTP
try
{
$mail->Host = 'localhost'; // SMTP server
$mail->SMTPDebug = 2; // enables SMTP debug information (for testing)
//$mail->AddReplyTo($from, $fromname);
$mail->AddAddress($to);
$mail->SetFrom($from, $fromname);
$mail->Subject = $subject;
//$mail->AltBody = $alt; // optional - MsgHTML will create an alternate automatically
$mail->MsgHTML($body);
$mail->Send();
echo 'Message Sent OK';
}
catch (phpmailerException $e)
{
echo $e->errorMessage(); //Pretty error messages from PHPMailer
}
catch (Exception $e)
{
echo $e->getMessage(); //Boring error messages from anything else!
}
}
That's the current function so far
Based on your code, if it's the class which is at fault, you'd expect to get 'Message Sent OK' twice (I can't see why that would happen though). If you don't, then I'd be looking at your SMTP server (maybe via a call to support).
I'm assuming you've disabled Reply-to to rule it out as a cause in this case? Note: I'm not suggesting that would affect anything (other than you likely being classified as spam).
Incidentally, I moved from PHPMailer to Swift Mailer some time ago & have never looked back. If you don't get any joy from support then I'd try at least testing with Swift Mailer.
I agree with what da5id said, why dont you take the second error message out. Further have you checked the receiver whether they REALLY get 2 messages?