I'm trying to use the phpemailer to send emails from my server. It's working fine except one thing:
<?php
$serverName = "xxx.x.x.xxx"; //serverName\instanceName
$connectionInfo = array( "Database"=>"test", "UID"=>"xxxxxx", "PWD"=>"xxxxxx");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn ) {
echo "Connection established.<br />";
}else{
echo "Connection could not be established.<br />";
die( print_r( sqlsrv_errors(), true));
}
$sqll=sqlsrv_query($conn,"select bla from table");
//while($row=sqlsrv_fetch_array($sql))
// {
// $cnp=substr($row['bla'],-6);
// echo $bla;
// echo "<br>";
// }
$con=mysqli_connect("localhost","root","","database");
$sql=mysqli_query($con,"select * from table");
if(isset($_POST['submitted'])){
require 'phpmailer/PHPMailerAutoload.php';
//Create a new PHPMailer instance
$mail = new PHPMailer;
//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 = 2;
$mail->SMTPAuth = true;
//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';
//Set the hostname of the mail server
$mail->Host = "xxxxxx";
//Set the SMTP port number - likely to be 25, 465 or 587
$mail->Port = xxx;
$mail->SMTPSecure = 'ssl';
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//Username to use for SMTP authentication
$mail->Username = "xxxxxx";
//Password to use for SMTP authentication
$mail->Password = "xxxxxx";
//Set who the message is to be sent from
$mail->setFrom('xxxxxx');
//Set an alternative reply-to address
$mail->addReplyTo('xxxxxx');
//Set who the message is to be sent to
while($row=mysqli_fetch_array($sql))
{
echo $row['bla'];
echo "<br>";
$mail->AddBCC($row['bla2']);
//Set the subject line
$mail->Subject = 'text text';
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
//Replace the plain text body with one created manually
$mail->Body = "test test<br>link:<a href='http://localhost:8181/?cod=".$bla."'>click</a>";
$mail->IsHTML(true);
$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
}
}
}
?>
<form name="contact" method="post" action="">
<input type="submit" name="submitted" value="Submit">
</form>
The problem is: I'm trying to send an email with a different link to every email I've got in my database. I had put this part between the while:
$mail->AddBCC($row['email']);
//Set the subject line
$mail->Subject = 'text text';
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
//Replace the plain text body with one created manually
$mail->Body = "test test<br>link:<a href='http://localhost:8181/?cod=".$bla."'>click</a>";
$mail->IsHTML(true);
$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
}
}
The emails are being sent but for example if i have 3 emails in my table then to email1 is sent the email 3 times, to email2 is sent 2 times and the email3 is sent one time. Why is that? why does the email being sent 3 times to the first email in my table?
I think, the problem is that you are adding the emails to the BCC, therefore, in the first loop, you are sending it to the first email, on the second, you are sending to the first email, and the newly added second email, and... so on...
You should clean the bcc before adding a new email.
call $mail->ClearBCCs() after $mail->send()
Clears all recipients assigned in the BCC array. Returns void.
--or--
Move your $mail->send() to after the loop to send all BCC addressed emails at once. (you may need to do this in batches depending on the mail server)
I've added the following line after I send the email:
$mail->ClearAllRecipients();
And now the emails are sent sent only one time. Thanks to all!
Related
I have thousands of emails and I want to send an e-mail to all of them and I can not solve it. Is anyone able to help and clarify with examples in ways of solving
As shown in the following code what is the problem and what is the solution
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'gator4164.hostgator.com '; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = "..."; // SMTP username
$mail->Password = '...'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
$mail->CharSet = 'UTF-8';
$get = new get();
$getEmails = $get->getEmails();
$CountEmails = $get->CountEmails();
$mail->setFrom('email#gmail.com', 'Email Name');
foreach($getEmails as $getEmails){
for ($x = $emails['id']; $x <= $CountEmails; $x++) {
$mail->addAddress($emails['email'],$emails['name']);
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $title;
$mail->Body = nl2br($content);
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
}
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo'<div class="done">Done</div>';
}
}
For such kind of scenario, you have to create a Process Queue because every email sending needs some time to process and if the email count is thousand then in that case your system will crash as it is having a processing time limit. For creating a process queue you have to maintain a database table in which save all the records and maintain a status with different values like:
0: Initial, 1:Processing, 2: Email Sent
And create a separate functionality that pick a record on a regular interval and send the email and change the status. Put this functionality on CRON.
Don't add all of the recipients with "add" in one loop then you have one Email with all recipients. Send your E-Mail with every duration.
foreach($getEmails as $getEmails){
$emails['email'] = $getEmails['email'];
$emails['name'] = $getEmails['name'];
$mail->addAddress($emails['email'],$emails['name']);
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $title;
$mail->Body = nl2br($content);
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo'Email send to ' + $emails['email'];
}
$mail->clearAddresses();
}
something like this. So send the Email for every duration. To prevent that you send people duplicate emails you should set the status in your database if the email is send otherwise you send it again if you have an error in your script and you have to restart the script.
Currently I am working on a PHP email script using PHPMailer` library. I am sending a mass mail using BCC for all the email addresses.
I want each email to contain the current recipient's email address in the message body.
Below is my sample code:
<?php
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->isSMTP();
$mail->Host = 'smtp1.example.com;smtp2.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'user#example.com';
$mail->Password = 'secret';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->setFrom('from#example.com', 'Mailer');
$mail->addAddress('noreply#example.com');
$arrMail [] = array('bcc1#example.com','bcc2#example.com');
for($i=0;$i<count( $arrMail);$i++)
{
$mail->addBCC($arrMail[$i]);
$htmlversion = 'Hello '.$arrMail[$i].' !'.
}
// $htmlversion = 'Hello <email_id needed here> !'.
$mail->Body = $htmlversion;
$mail->AltBody = $textVersion;
if(!$mail->send())
{
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
}
else
{
echo 'Mail sent';
}
Problem: If bcc1#example.com receives the email, its message body should contain their email address. Currently I am getting the first email address in the message body for every recipient.
Note: I dont want to send mail one-by-one using To like mentioned in other pages.
Also is it possible by using some session or database logic?
I am using php 5.5.9.
Your code is reusing the same email address because you didn't put the creation of the mail body in the loop. If you use a loop then you also don't need BCC.
$arrMail [] = array('bcc1#example.com', 'bcc2#example.com');
$total = count($arrMail);
for($i = 0; $i < $total; $i++) {
$email = $arrMail[$i];
$htmlversion = "Hello $email !";
$mail->Body = $htmlversion;
$mail->AltBody = $textVersion;
$mail->AddAddress($email);
if (!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Mail sent';
}
}
I dont want to send mail one-by-one using To like mentioned in other pages.
Unfortunately, BCC by its very nature sends the same email to multiple recipients. If you want to customise each email for each person, you have to send them individual emails.
I'm using PHPMailer to send an email from a form to all the emails in a MySQL database.
I've managed to get the form to send an email to each email but I'm now trying to use their name in the email sent to them meaning each email woud begin with "Hello, [their-name],".
I'm using an array to loop through the results of my database query and adding each email and name as $mail->addAddress('email#email.com, 'name');
I've tried saving the variable $name = $row['name'}; inside the while loop but it inputs the last name from the database into all the emails.
My question is: Is it possible to access the 'name' part of the function and use it each email. Or is it better to take their name from the database itself? And if so how would I go about doing that?
Also, when the email sends to each recipient, it shows all of the recipients in the "To:" field. This would be pretty bad for privacy. Is there a way to prevent this?
I'm fairly new to PHP and MySQL still so explanatory answers would be greatly appreciated.
Please find my code below.
<?php
// Take message value from form
$message = preg_replace("/\r\n|\r/", "<br />", $_REQUEST['message']);
$message = trim($message);
// Error reporting on
error_reporting(E_STRICT | E_ALL);
date_default_timezone_set('Etc/UTC');
// Require PHPMailer
require 'PHPMailer/PHPMailerAutoload.php';
$mail = new PHPMailer;
$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 = 587;
$mail->Username = 'my#email.com';
$mail->Password = 'mypassword';
$mail->setFrom('myemail#email.com', 'Me');
$mail->addReplyTo('myemail#email.com', 'Me');
$mail->Subject = "Newsletter";
/* ----- Add address function below ----- */
// Require Database connection
require 'dbcon.php';
// SELECT email and name values from database
$query = "SELECT email, name FROM customers";
// Result = the database query
$result = $con->query($query);
// Get array of users email addresses and names.
while($row = $result->fetch_array())
{
// Add recipients from values found in database
$mail->addAddress($row["email"], $row["name"]);
}
/* ----- Add address function above ----- */
$mail->Body ="Hello, <br> <br> $message";
$mail->AltBody = $message;
if(!$mail->Send())
{
echo "Message could not be sent.";
echo "Mailer Error: " . $mail->ErrorInfo;
exit;
}
print 'Sent!';
?>
You are currently setting up to send a single email with several recipients. For security and etiquette, you should address the email to yourself (outside the loop):
$mail->addAddress('myemail#email.com', 'Me');
...and then add all of the recipients as BCC (inside the loop):
$mail->addBCC($row["email"], $row["name"]);
As for the name field. Add a debug line inside your loop and take a look at your output. Is the name field the same each time?
print "Adding recipient: {$row['email']} {$row['name']}";
If you want to sent several emails, one to each recipient, you need to instantiate a new email inside the loop each time.
[UPDATE]
If you want to send a single message to each recipient, then instantiate a new email each time (inside your loop):
<?php
// Take message value from form
$message = preg_replace("/\r\n|\r/", "<br />", $_REQUEST['message']);
$message = trim($message);
// Error reporting on
error_reporting(E_STRICT | E_ALL);
date_default_timezone_set('Etc/UTC');
// Require PHPMailer
require 'PHPMailer/PHPMailerAutoload.php';
// Require Database connection
require 'dbcon.php';
// SELECT email and name values from database
$query = "SELECT email, name FROM customers";
// Result = the database query
$result = $con->query($query);
// Get array of users email addresses and names.
while($row = $result->fetch_array())
{
// Instantiate a NEW email
$mail = new PHPMailer;
// Set the email settings
$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 = 587;
$mail->Username = 'my#email.com';
$mail->Password = 'mypassword';
$mail->setFrom('myemail#email.com', 'Me');
$mail->addReplyTo('myemail#email.com', 'Me');
$mail->Subject = "Newsletter";
// Add recipient from values found in database
$mail->addAddress($row["email"], $row["name"]);
$mail->Body ="Hello, <br> <br> $message";
$mail->AltBody = $message;
if(!$mail->Send())
{
echo "Message could not be sent.";
echo "Mailer Error: " . $mail->ErrorInfo;
exit;
}
print "Sent mail to: {$row["email"]}, {$row["name"]}";
}
?>
Email sends correctly, but then everything on my submission page disappears (although in the url it says it is the same page) except the echo statement saying 'Message sent successfully'.
I want to have a 'congratulations' page or something less cheesy to greet the user after they are sent the validation email...
I've tried searching the class.phpmailer.php for a redirect function but theres nothing. I'm sure its something simple but I cant seem to locate whats causing this.
<?php
require ('/config.inc.php');
require '../PHPMailer/PHPMailerAutoload.php';
if(mysqli_affected_rows($dbc) == 1){
$mail = new PHPMailer;
$mail->isSMTP();
$mail->SMTPSecure = 'ssl';
$mail->Host = "smtp.gmail.com"; // SMTP server
$mail->Port = 465;
$mail->SMTPAuth = true;
$mail->Username = "censored#gmail.com";
$mail->Password = "censored";
//Set who the message is to be sent from
$mail->setFrom('censored#gmail.com');
//Set an alternative reply-to address
$mail->addReplyTo('censored#gmail.com');
//Set who the message is to be sent to
$mail->addAddress($trimmed['email']);
//Set the subject line
$mail->Subject = 'PHPMailer mail() test';
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
$mail->msgHTML('Thank you for registering at The Circle Of Pi. To activate your account,
please click on this link:\n\n' . BASE_URL . 'activate.php?x=' . urlencode($e) . "&y=$a");
//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';
//Attach an image file
//$mail->addAttachment('images/phpmailer_mini.png');
//send the message, check for errors
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!1";
}
exit();
}else {
echo '<p class=\"error\">You could not be registered due to a system error. We apologize
for any inconvenience.</p>';
}
}else{
echo '<p class = \"error\">That email address has already been registered. If you have
forgotten your password, use the link at the right to have your password sent to you</p>';
}
} else {
echo '<p class = \"error\">Please try again.</p>';
}
mysqli_close($dbc);
}
?>
If your request is POST then you're calling exit() after 'Message sent!1' echo.
else {
echo "Message sent!1";
}
exit();
On your:
<form method="post">
Add a action to it such as:
<form method="post" action="{pickaname}.php">
and create a file called {pickaname}.php and make it when all the data is inserted it will redirect the user to your congratulations page.
i am trying to send bulk email using phpmailer i have more than 10 email id's in my database when i click on send button then first email will go to one person, the second email sent will go to that same person plus another, the third one will go to those two plus one more, and so on. this is my coding please help me
<?php
$body=$_POST['message'];
$subject=$_POST['sub'];
//error_reporting(E_ALL);
error_reporting(E_STRICT);
date_default_timezone_set('America/Toronto');
require_once("class.phpmailer.php");
//include("class.smtp.php");
$mail = new PHPMailer();
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = "stmp.gmail.com"; // SMTP server
$mail->SMTPDebug = 1; // enables SMTP debug information
// 1 = errors and messages
// 2 = messages only
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->SMTPSecure = 'ssl';
$mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->CharSet = "big5";
$mail->Username = "abc#gmail.com"; // GMAIL username
$mail->Password = "**********"; // GMAIL password
$mail->SetFrom("abc#gmail.com", ''); // set reply id
$mail->Subject = ($subject); // subject
$mail->MsgHTML("$body"); // message
$mail->AddAddress($address, "abc");
$con=mysql_connect("localhost","root","") or
die("could not connect:".mysql_error());
mysql_select_db("bulkemail");
$qry=mysql_query("SELECT * FROM email_id", $con);
if(!$qry)
{
die("Query Failed: ". mysql_error());
}
while($row = mysql_fetch_array($qry))
{
$id= $row["email"];
$address = ($id);
$mail->AddBcc($id);
$mail->send();
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
}
else {
echo "Message sent!";
}
}
?>
Remove $mail->send(); and move if(!$mail->Send()) to outside the while($row ..) loop
while($row = mysql_fetch_array($qry)){
$id= $row["email"];
$address = ($id);
$mail->AddBcc($id);
} // end the while loop
// remove $mail->send(); as it is a duplicate of if(!$mail->Send())
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
}
else {
echo "Message sent!";
}
I had used phpmailer for mass mailing and I had same problem.
while($row = mysql_fetch_array($qry)){
$id= $row["email"];
$address = ($id);
$mail->AddBcc($id);
//imo if should be in the while loop.
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
}
else {
echo "Message sent!";
//I added this function down there so that old address would be removed but in the new loop, new one will be added.
$mail-> ClearAddresses();
}
} // end the while loop
This works for me.
In your case, you are adding a new BCC to the list of all BCC already send in every repeat of the loop.
Like "kworr Sep 27 '13 at 18:36 " said, you need to create new instance for every sending in the loop.
Or you need to put
$mail->send();
out of the loop.