Mike T
Mike T

Reputation: 29

PHPMailer sends multiple emails with loop

i use the following code to send mail with PHPMailer.It sends the emails to the recipients from db ,but it sends many emails to them.I want to send them only 1 with the related records in the HTML Table for each user.eg. if there are 5 records returned for a user then it sends 5 emails to the user with 1 record inside. Also,i don't want to use the try and catch commands the default PHPMailer script uses,but while ...

How can i change it to do what i want? Thank you.

<?php
$stmt = sqlsrv_query( $conn, $sql );   

$rows = array();
while($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)){

$rows[] = $row; 

//foreach ($result as $row) {
try {


    $mail->addAddress($row['email']);
} 
   catch (Exception $e) {
    echo 'Invalid address skipped: ' . htmlspecialchars($row['email']) . '<br>';
    continue;
}

try {
    $body = 'Hi: '. $row['first'] .' '. $row['last'] .'<br>';
    $body .=  '<table border="1"><tr><th>Username</th><th>Day</th><th>Date</th></tr><th>Action</th>';

    $body .= '<tr><td>';         
    $body .= $row['username'] . '</td><td>'; 
    $body .= $row['day'] . '</td><td>';  
    $body .= $row['date'] . '</td><td>';                        
    $body .= $row['action'] . '</td></tr>';
    $body .= '</table>';      

    $mail->msgHTML($body);

    $mail->send();
    echo 'Message sent to :' . htmlspecialchars($row['last']) . ' '. htmlspecialchars($row['first']) . '(' . htmlspecialchars($row['email']) . ')<br>';


} catch (Exception $e) {
    echo 'Mailer Error (' . htmlspecialchars($row['email']) . ') ' . $mail->ErrorInfo . '<br>';
    $mail->smtp->reset();
}

$mail->clearAddresses();
$mail->clearAttachments();
 }
?>

Upvotes: 1

Views: 1455

Answers (2)

Mike Volmar
Mike Volmar

Reputation: 2093

is this what you mean? send all results to each person in result set only once?

$stmt = sqlsrv_query( $conn, $sql );   

$rows = array();
$body = '<table border="1"><tr><th>Username</th><th>Day</th><th>Date</th></tr><th>Action</th>';

while($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)){

  $rows[] = $row; 
  $name = $row['first'] .' '. $row['last'];

  $body .= '<tr><td>';         
  $body .= $row['username'] . '</td><td>'; 
  $body .= $row['day'] . '</td><td>';  
  $body .= $row['date'] . '</td><td>';                        
  $body .= $row['action'] . '</td></tr>';


  $mail->addAddress($row['email'], $name);

}
$body .= '</table>'; 
$mail->msgHTML($body);

$mail->send();

Here is an example of the double while loops. $sql = select all the people & email addresses within your timeframe or other section criteria

$stmt = sqlsrv_query( $conn, $sql );  
while($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)){

  $name = $row['first'] .' '. $row['last'];
  $email = $row['email'];
  $body = '<table border="1"><tr><th>Username</th><th>Day</th><th>Date</th></tr><th>Action</th>';

  // now get this person's messages

  $sql2 = "SELECT username, day, date, action from Message WHERE name = $row['name']";

  $stmt2 = sqlsrv_query( $conn, $sql2 );  
  while($row2 = sqlsrv_fetch_array( $stmt2, SQLSRV_FETCH_ASSOC)){
    $body .= '<tr><td>';         
    $body .= $row['username'] . '</td><td>'; 
    $body .= $row['day'] . '</td><td>';  
    $body .= $row['date'] . '</td><td>';                        
    $body .= $row['action'] . '</td></tr>';
  }
  $body .= '</table>';

  // at this point you can create the phpmailer add the single email address & message body, and send the email

}

OK, here is something you can try to reorganize the results. You can replace the $testing array with your SQL result set. Using two foreach loops you can reorganize it into a multidimensional array $names and then loop thru that to send your emails.

$test1 = array('name'=>'mike','email'=>'mike@mike','day'=>'monday','action'=>'acrtion1');
$test2 = array('name'=>'mike','email'=>'mike@mike','day'=>'tuesday','action'=>'acrtion2');
$test3 = array('name'=>'mike','email'=>'mike@mike','day'=>'wedday','action'=>'acrtion3');

$test4 = array('name'=>'dave','email'=>'dave@mike','day'=>'monday','action'=>'acrtion1');
$test5 = array('name'=>'dave','email'=>'dave@mike','day'=>'tuesday','action'=>'acrtion2');
$test6 = array('name'=>'dave','email'=>'dave@mike','day'=>'wedday','action'=>'acrtion3');

$test7 = array('name'=>'tom','email'=>'tom@mike','day'=>'monday','action'=>'acrtion1');
$test8 = array('name'=>'tom','email'=>'tom@mike','day'=>'tuesday','action'=>'acrtion2');
$test9 = array('name'=>'tom','email'=>'tom@mike','day'=>'wedday','action'=>'acrtion3');

$testing = array($test1,$test2,$test3,$test4,$test5,$test6,$test7,$test8,$test9);

$names = array();

foreach($testing as $test){
    $names[$test['name']][] = $test;
}

print_r($names);

foreach($names as $name=>$records){
    echo "<p>email $name";
    foreach($records as $record){
        // this is where you can construct the email body for current $name
        echo "<p>".$record['email']." ".$record['day']." ".$record['action'];
    }
    // now send the email to current $name
}

Upvotes: 1

Mike T
Mike T

Reputation: 29

My sql returns the following result.The 'email' has to be GROUPED BY???

enter image description here

Upvotes: 0

Related Questions