Reputation: 75
I have a problem that my current php send duplicate emails using PHPMailer. The php file is to be run by a cronjob, but for we just run it manually.
I tried $mail->ClearAddresses(); but that didn't seem to help.
When we vardump $mail; but it looks like it is only sent once, and our "Message has been sent" message is only being printed once pr email adress in our database.
We also tried select distinct which was suggested in another thread, but it seemed to have no effect.
We also tried adding a counter to different places of the script, but it displayed the correct number of iterations.
<?php
ini_set("allow_url_fopen", 1);
include '/home/actiorwd/include/dbinfo.php';
$counter =0;
$servername = "localhost";
$dbname = "actiorwd_websec";
// Create connection
$conn = new mysqli($servername, $user, $passw, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT DISTINCT * FROM users";
$result = $conn->query($sql);
$ch = curl_init();
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$url = 'https://haveibeenpwned.com/api/v2/breachedaccount/';
$url.= $row["email"];
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
curl_setopt($ch, CURLOPT_URL, $url);
$results = curl_exec($ch);
$obj = json_decode($results, TRUE);
$newbreaches = count($obj);
//run if new breaches are found
if($row["breaches"]!==$newbreaches){
require_once('/home/actiorwd/public_html/PHPMailer/PHPMailerAutoload.php');
$mail = new PHPMailer;
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'cpanel40.proisp.no'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = '[email protected]'; // SMTP username
$mail->Password = 'PASSWORDHERE'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
$mail->setFrom('[email protected]', 'WebSec');
$mail->ClearAddresses();
$mail->addAddress($row["email"]); // Add a recipient
$mail->addReplyTo('[email protected]', 'WebSec');
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Breached!!!!';
$mail->Body = 'Someone hacked your account, there are: '.$newbreaches."breaches";
$mail->AltBody = 'Someone hacked your account in plain text';
$mail->send();
if(!$mail->send()) {
echo 'Message could not be sent.<br />';
echo 'Mailer Error: ' . $mail->ErrorInfo . '<br />';
} else {
echo 'Message has been sent <br />';
$counter++;
}
$updatebreach = "INSERT INTO users (`email`, `breaches`) VALUES ('$usermail', '$newbreaches') ON DUPLICATE KEY UPDATE `breaches` = '$newbreaches' ";
//echo $updatebreach;
if ($conn->query($updatebreach) === TRUE) {
echo "New record created successfully <br />";
} else {
echo "Error: " . $updatebreach . "<br>" . $conn->error;
}
}
sleep(2);
}
} else {
echo "0 results";
}
curl_close($ch);
echo $counter;
$conn->close();
?>
Upvotes: 1
Views: 209
Reputation: 13635
You are calling $mail->send()
twice:
$mail->send();
if(!$mail->send()) { // <--- Here you're actually sending it again.
echo 'Message could not be sent.<br />';
echo 'Mailer Error: ' . $mail->ErrorInfo . '<br />';
} else {
echo 'Message has been sent <br />';
$counter++;
}
You should store the result of the first send instead like this:
// Store the status in a variable instead
$sent = $mail->send();
if(!$sent) { // Check the result of the variable instead of sending it again
echo 'Message could not be sent.<br />';
echo 'Mailer Error: ' . $mail->ErrorInfo . '<br />';
} else {
echo 'Message has been sent <br />';
$counter++;
}
Upvotes: 2