This question already has answers here:
PHPMailer email sent successfully but not received (EC2)
(3 answers)
PHP mail function doesn't complete sending of e-mail
(31 answers)
Closed 5 years ago.
I am using PHPmailer now for the first time, because I need to use attachments in future and the build in mail is not so good for that.
I am playing around with the example code and eventhough I get no errors + Message has been sent no messages arrive at the destination email.
Here is the code I use. The uncommented things can be ignored (I need them for a form, on submit an email should be sent)
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
//Load composer's autoloader
require '../vendor/autoload.php';
// Fetching Values from URL.
//$phone = $_POST['phone1'];
//$email_var = $_POST['email1'];
$email_var = 'sender.email.info#gmx.net';
$email_var = filter_var($email_var, FILTER_SANITIZE_EMAIL); // Sanitizing E-mail.
// After sanitization Validation is performed
if (filter_var($email_var, FILTER_VALIDATE_EMAIL)) {
$mail = new PHPMailer(); // Passing `true` enables exceptions
try {
//$mail->SMTPDebug = 2; // Enable verbose debug output
//$mail->isSMTP(); // Set mailer to use SMTP
//$mail->Host = 'SERVER'; // Specify main and backup SMTP servers
//$mail->SMTPAuth = true; // Enable SMTP authentication
//$mail->Username = 'USER'; // SMTP username
//$mail->Password = 'PW'; // SMTP password
//$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
//$mail->Port = 465; // TCP port to connect to
//Recipients
$mail->setFrom('receiver.email#gmx.net');
//$mail->addAddress('receiver.email#gmx.net'); // Add a recipient
//Attachments
//$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
//Content
$mail->isHTML(true);
$mail->Subject = 'Here is the subject';
$mail->Body = '<div style="padding:50px; color:white;">'
. '<br/> Kautionsrückzahlung Interesse von: <br/><br/>'
//. 'Telefon: ' . $phone . '<br/>'
. 'Email: ' . $email_var . '<br/>';
$mail->AltBody = '<div style="padding:50px; color:white;">'
. '<br/> Kautionsrückzahlung Interesse von: <br/><br/>'
//. 'Telefon: ' . $phone . '<br/>'
. 'Email: ' . $email_var . '<br/>';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
}
}
I tryed now different things, it seems it does not matter whether I use server PW etc. I assume its only for localhost.
EDIT:
To clarify, I am not on localhost. I have the data for my server, but obviously I dont include the data in the question. I changed them to USER, SERVER and PW.
But it does not matter whether they are there or uncommented I get Message has been sentin both cases.
do you really need that to be done in your local host. instead you can deploy the code in any host and check. you don't have to use any additional stuff. simple mail option is enough. reason is in your local server no mail server configured. so you using some other class to achieve that.
Did you checked on Server host ?
Related
How do I get rid of this footer in my messages?
require ('PHPMailerAutoload.php');
$mail = new PHPMailer;
// Form Data
$name = $_REQUEST['name'] ;
$subject = $_REQUEST['subject'] ;
$email = $_REQUEST['email'] ;
$message = $_REQUEST['message'] ;
$mailbody = 'Information' . PHP_EOL . PHP_EOL .
'Name : ' . $name . '' . PHP_EOL .
'E-mail Address : ' . $email . '' . PHP_EOL .
'Message : ' . $message . '' . PHP_EOL;
// $mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'sample#gmail.com'; // SMTP username
$mail->Password = 'xxxxxxxxxxx'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->setFrom('sample#gmail.com', 'WebMaster'); // Admin ID
$mail->addAddress('sample#gmail.com', 'Admin'); // Business Owner ID
$mail->addReplyTo($email, $name); // Form Submitter's ID
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $mailbody;
// $mail->send();
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
}
You are using free hosting so you cannot remove this.
This advertisement is automatically attached by the hosting providers as you use their hosting.
Its better to use a paid hosting or try free trials of GOOGLE CLOUD/AWS/MICROSOFT AZURE
Your hosting provider is able to do this because you're doing this:
// $mail->isSMTP();
By commenting out this line, PHPMailer falls back to sending via PHP's mail() function. This way of sending sends through a local mail server without any encryption, and your provider is exploiting that fact in order to inject the footer you're seeing.
If you use a secure transport, such as by using SMTP with TLS to gmail, your provider is denied that opportunity because they can't see (let alone interfere with) your messages, and the footer would not appear.
However, its likely that you commented out that line because your SMTP configuration wasn't working, and that's likely to be because your hosting provider blocks outbound SMTP, which is very common, especially at the low end.
I am having issues with mail NOT going to all email addresses sometimes. I have been testing from a web-app I built and it is hosted with GoDaddy with "Deluxe" shared hosting level.
Is it possible that I have upset the GoDaddy Email Server gods by submitting too many test email sends??
Is it possible that my emails are being blocked because the servers think my multiple tests are spam? I do receive SOME of the emails....
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
//Load Composer's autoloader
require 'vendor/autoload.php';
$mail = new PHPMailer(true); // Passing `true` enables exceptions
try {
// Server settings
$mail->SMTPDebug = 2; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'xxxxxxxxxxxx.prod.phx3.secureserver.net'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'cpanelusername'; // SMTP username
$mail->Password = 'cpanelpassword'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
// Recipients - Names are optional - $mail->setFrom('xxxxxxxxxx#cox.net', 'Peter Henry Lee');
$mail->setFrom('xxxxxxxxxx#cox.net'); // From Address
$mail->addAddress('xxxxxxxxxx#cox.net'); // Recipient 1
$mail->addAddress('xxxxx#cox.net'); // Recipient 2
$mail->addCC('xxxxxxx#cox.net'); // Cc 1 Address
$mail->addCC('xxxxxxxx#cox.net'); // Cc 2 Address
$mail->addBCC('xxxxxxxxx#xxxxesigns.com'); // Bcc Address
// $mail->addReplyTo('xxxxxxxxx#xxxxesigns.com'); // Reply-To Address
// Attachments
include 'retrieve_order.php'; // Retrieves PDF
$mail->addAttachment('receipts/' . $newname); // Adds PDF attachment
// $mail->addAttachment('img/puppy2.png', 'Puppy is cute!'); // Adds Image attachment with optional name
// Content
$newname = substr($newname, 0, 11);
$l = $newname;
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the TEST ' . $l . ' subject line';
$mail->Body = 'This is the TEST ' . $l . ' HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the TEST ' . $l . ' body in plain text for non-HTML mail clients';
// Send mail
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
}
I have this problem where when I receive an email sent from my localhost website, I get the wrong email address for the for the sender section ($mail->SetFrom($email, $name)). I get my own email address as the sender and not the one inputed in the text box on my website.
I've looked everywhere for some answers, sadly nothing worked. I've tried going on Chrome Account Settings and setting the less secure apps to ON. That didn't work.
I've tried multiple ways of setting the SetFrom email and name. NEED HELP!
<?php
$dir = __DIR__;
require_once("$dir/../PHPMailer-master/PHPMailerAutoload.php");
extract($_POST, EXTR_PREFIX_ALL, "P");
$name = $_POST['postName'];
$email = $_POST['postEmail'];
$subject = $_POST['postSubject'];
$message = $_POST['postMessage'];
$file = $_POST['postFile'];
echo "Name: ".$_POST['postName'];
echo "\n";
echo "Email: ".$_POST['postEmail'];
echo "\n";
echo "Subject: ".$_POST['postSubject'];
echo "\n";
echo "Message: ".$_POST['postMessage'];
echo "\n";
echo "File: ".$_POST['postFile'];
$mail = new PHPMailer;
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = "mail.gmail.com"; // SMTP server
//$mail->SMTPDebug = 2; // enables SMTP debug information (for testing)
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->SMTPSecure = "tls"; // sets the prefix to the servier
$mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server
$mail->Port = 587; // set the SMTP port for the GMAIL server
$mail->Username = "xxxx#gmail.com"; // GMAIL username
$mail->Password = "xxxx"; // GMAIL password
$mail->SetFrom($email, $name);
$mail->AddReplyTo($email, $name);
$mail->addAddress("xxxx#gmail.com", "name");
$mail->AddAttachment("$file");
$mail->Subject = "$subject";
$mail->Body = "$message";
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
} ?>
This is an alert I set up showing all the POST parameters sent to the my PHP script. All the POST variables are there. The only problem is the SetFrom($email, $name)
Javascript Alert with POST Parameters
Gmail does not allow you to set arbitrary from addresses, though you can define preset aliases.
However, you shouldn't be trying to do this anyway. Putting user-provided value in the from address is a very bad idea as your messages will fail SPF checks because it's forgery. Put your own address in the from address (as well as the to address), and put the submitter's address in a reply-to header using the addReplyTo() method. You can see this working in the contact form example provided with PHPMailer:
//Use a fixed address in your own domain as the from address
//**DO NOT** use the submitter's address here as it will be forgery
//and will cause your messages to fail SPF checks
$mail->setFrom('from#example.com', 'First Last');
//Send the message to yourself, or whoever should receive contact for submissions
$mail->addAddress('whoto#example.com', 'John Doe');
//Put the submitter's address in a reply-to header
//This will fail if the address provided is invalid,
//in which case we should ignore the whole request
if ($mail->addReplyTo($_POST['email'], $_POST['name'])) {
...
This question already has answers here:
PHP mail function doesn't complete sending of e-mail
(31 answers)
Closed 6 years ago.
I want to use the PHP mail function to send a HTML form to my mail.
When I run the code it no error occurs, but I don't receive an email.
I used the following code:
<?php
$to = 'email#email.com';
$subject = 'Subject';
$message = 'Message here';
$headers = 'From: email#email.com' . "\r\n" .
'Reply-To: webmaster#example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
?>
I'm hosting my web app on Microsoft Azure with PHP 7.0.
I assume Microsoft turned PHP mail off. (many hosting providers do)
Microsoft says that you should use SendGrid. You can read the full tutorial here: https://azure.microsoft.com/en-us/documentation/articles/store-sendgrid-php-how-to-send-email/
I've tried to use the php mail() function but I can't get it working so I've searched for some answers and this works:
https://github.com/PHPMailer/PHPMailer
You can use it when you will send a mail to a gmail account or for local email servers.
Notes:
Make sure your path for PHPMailerAutoload.php is correct when you are requiring. For example:
require 'assets/api/PHPMailer-master/PHPMailerAutoload.php';
You must know the host name if you are going to send to a local email server.
You must have an account that you can use to send a mail.
Analyze how the code works and feel free to comment for further questions.
I'll attach a sample code here from a website I developed.
<?php
$strFullname = $strEmail = $strMobile = $strPosition = "";
require 'assets/api/PHPMailer-master/PHPMailerAutoload.php';
//Create a new PHPMailer instance
$mail = new PHPMailer(true);
//Tell PHPMailer to use SMTP
$mail->isSMTP();
//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
//$mail->SMTPDebug = 1;
//Ask for HTML-friendly debug output
//a$mail->Debugoutput = 'html';
//Set the hostname of the mail server
$mail->Host = 'secure.emailsrvr.com';
// use
// $mail->Host = gethostbyname('smtp.gmail.com');
// if your network does not support SMsTP over IPv6
//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = 587;
//Set the encryption system to use - ssl (deprecated) or tls
$mail->SMTPSecure = 'tls';
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//Username to use for SMTP authentication - use full email address for gmail
$mail->Username = "myemail#mailserver.com";
//Password to use for SMTP authentication
$mail->Password = "myaccountpassword";
//Set who the message is to be sent from, you can use your own mail here
$mail->setFrom('bpsourceph#gmail.com', '#noreply.bpsource.com');
//Set an alternative reply-to address
//$mail->addReplyTo('replyto#example.com', 'First Last');
//Set who the message is to be sent to
$mail->addAddress('testmail#mailserver.com', 'Firstname Lastname');
//Set the subject line
$mail->Subject = 'New application form sent from ***** Career page';
$mail->IsHTML(true);
//Attach an image file
//$mail->addAttachment('images/phpmailer_mini.png');
if($_SERVER["REQUEST_METHOD"]=="POST")
{
$strFullname = $_POST['strFullname'];
$strEmail = $_POST['strEmail'];
$strMobile = $_POST['strMobile'];
$strPosition = $_POST['strPosition'];
//This part is where you will create your mail
$mail->msgHTML("Fullname: ".$strFullname."\nEmail: ".$strEmail."\nMobile Number: ".$strMobile."\nDesired Position: ".$strPosition);
//This part is for sending the mail
if (!$mail->send()) {
//If you want to check for errors. Uncomment the line below.
//echo "Mailer Error: " . $mail->ErrorInfo;
echo "<script>alert('Some error occured. Please try again later');</script>";
header("Refresh:2");
}
echo "<script>alert('Application form successfully sent!');</script>";
header("Refresh:2");
}
?>
Hope I am getting things clear for you. Regards! Goodluck!
Edit: I forgot I'd created the SendMail(); function myself, which is why the explanation doesn't mention at first what it does.
I'm having some trouble with PHPMailer (https://github.com/PHPMailer/PHPMailer) when attempting to send two emails, one directly after the other.
The script is almost completely 'out of the box', with only a few modifications such as a foreach loop to allow for multiple addresses, and everything still works perfectly.
However, if I attempt to call more than one instance of SendMail(); I get the error message:
Fatal error: Cannot override final method Exception::__clone() in .... online 0
Previously I was using the in-built mail(); function, which allowed me to use it as many times as I liked in quick succession , but it doesn't appear to be that simple with PHPmailer:
$to = me#me.com;
$to2 = me2#me2.com';
$headers = 'php headers etc';
$subject = 'generic subject';
$message = 'generic message';
mail($to, $subject, $message, $headers);
mail($to2, $subject, $message, $headers);
The above would result in two identical emails being sent to different people, however I can't easily replicate this functionality with PHPmailer.
Is there a way of stacking these requests so that I can send successive emails without it failing? Forcing the script to wait until the first email has been sent would also be acceptable, although not preferential.
As I mentioned I know it works when only one instance is called, but I don't seem to be able to re-use the function.
I haven't included the source code, although it is all available on the link provided above.
Thanks in advance
Edit as requested
// First Email
$to = array(
'test#test.com',
'test2#test.com',);
$subject = "Subject";
$message = $message_start.$message_ONE.$message_end;
sendMail();
// Second Email
$to = array(
'test#test.com',
'test2#test.com',);
$subject = "Subject";
$message = $message_start.$message_TWO.$message_end;
sendMail();
The above is how I want this to work, as it would work with mail();. The first email will work fine, the second will not.
SendMail() code
This is from the PHPmailer website, and is what is defined as SendMail();. The only difference from the example is the loop for AddAddress, and the inclusion of $to as a global variable.
$mail = new PHPMailer();
$mail->IsSMTP(); // set mailer to use SMTP
$mail->Host = "smtp1.example.com;smtp2.example.com"; // specify main and backup server
$mail->SMTPAuth = true; // turn on SMTP authentication
$mail->Username = "jswan"; // SMTP username
$mail->Password = "secret"; // SMTP password
$mail->From = "from#example.com";
$mail->FromName = "Mailer";
foreach($to as $to_add){
$mail->AddAddress($to_add); // name is optional
}
$mail->AddReplyTo("info#example.com", "Information");
$mail->WordWrap = 50; // set word wrap to 50 characters
$mail->AddAttachment("/var/tmp/file.tar.gz"); // add attachments
$mail->AddAttachment("/tmp/image.jpg", "new.jpg"); // optional name
$mail->IsHTML(true); // set email format to HTML
$mail->Subject = "Here is the subject";
$mail->Body = "This is the HTML message body <b>in bold!</b>";
$mail->AltBody = "This is the body in plain text for non-HTML mail clients";
if(!$mail->Send())
{
echo "Message could not be sent. <p>";
echo "Mailer Error: " . $mail->ErrorInfo;
exit;
}
echo "Message has been sent";
You haven't posted this code that lets me make this a complete conclusion, but from the Exception and the way you've defined an overriding class inside a function, you probably have class.phpmailer.php loading every time like this:
require('class.phpmailer.php');
or
include('class.phpmailer.php');
You should change that line to
require_once('class.phpmailer.php');
The reason you need to change it to require_once is so that PHP will not load the class file the second time when you try to create the new/second PHPMailer class. Otherwise, the line class PHPMailer throws the __clone() exception.
Added an example below:
<?php
/**
* This example shows how to send a message to a whole list of recipients efficiently.
*/
//Import the PHPMailer class into the global namespace
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
error_reporting(E_STRICT | E_ALL);
date_default_timezone_set('Etc/UTC');
require '../vendor/autoload.php';
//Passing `true` enables PHPMailer exceptions
$mail = new PHPMailer(true);
$body = file_get_contents('contents.html');
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent, reduces SMTP overhead
$mail->Port = 25;
$mail->Username = 'yourname#example.com';
$mail->Password = 'yourpassword';
$mail->setFrom('list#example.com', 'List manager');
$mail->addReplyTo('list#example.com', 'List manager');
$mail->Subject = 'PHPMailer Simple database mailing list test';
//Same body for all messages, so set this before the sending loop
//If you generate a different body for each recipient (e.g. you're using a templating system),
//set it inside the loop
$mail->msgHTML($body);
//msgHTML also sets AltBody, but if you want a custom one, set it afterwards
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!';
//Connect to the database and select the recipients from your mailing list that have not yet been sent to
//You'll need to alter this to match your database
$mysql = mysqli_connect('localhost', 'username', 'password');
mysqli_select_db($mysql, 'mydb');
$result = mysqli_query($mysql, 'SELECT full_name, email, photo FROM mailinglist WHERE sent = FALSE');
foreach ($result as $row) {
try {
$mail->addAddress($row['email'], $row['full_name']);
} catch (Exception $e) {
echo 'Invalid address skipped: ' . htmlspecialchars($row['email']) . '<br>';
continue;
}
if (!empty($row['photo'])) {
//Assumes the image data is stored in the DB
$mail->addStringAttachment($row['photo'], 'YourPhoto.jpg');
}
try {
$mail->send();
echo 'Message sent to :' . htmlspecialchars($row['full_name']) . ' (' . htmlspecialchars($row['email']) . ')<br>';
//Mark it as sent in the DB
mysqli_query(
$mysql,
"UPDATE mailinglist SET sent = TRUE WHERE email = '" .
mysqli_real_escape_string($mysql, $row['email']) . "'"
);
} catch (Exception $e) {
echo 'Mailer Error (' . htmlspecialchars($row['email']) . ') ' . $mail->ErrorInfo . '<br>';
//Reset the connection to abort sending this message
//The loop will continue trying to send to the rest of the list
$mail->getSMTPInstance()->reset();
}
//Clear all addresses and attachments for the next iteration
$mail->clearAddresses();
$mail->clearAttachments();
}
In addition to #Amr most excellent code.
In order to use this in a cron fasion, two adds are useful.
$mail-> SMTPDebug = true;
$mail-> Debugoutput = function( $str, $level ) {_log($str);};
The function _log is up to you. Writing to a file, to a database or wherever. I personally have reduced this to
$mail-> Debugoutput = function( $str, $level ) {if( $level===3 ) {_log( $str ); } };
to only write the more juicier messages
the solution is to reset recipients data like this:
$Mailer->clearAddresses()
use your own variable as an instance of PHPMailer (instead of $Mailer)
$Mailer->clearAddresses()
This is the solution to avoid multiple msj to be send to the same recipient.