Link to home
Start Free TrialLog in
Avatar of Eduardo Fuerte
Eduardo FuerteFlag for Brazil

asked on

Could you have a look at this PHP script using PHPMailer to see its correction?

Hi Experts

Could you have a look at this PHP script using PHPMailer to see its correction?

After some tests with a small number of address it run well.
But then, when using the complete base - about 750 address it seens to be erratic!

f.e.  - My own email address had received 03 copies of the same email, after a while my SMTP provider warned me that I reached the limit of email sendings I could send in 01 hour.


<?php

   error_reporting(E_STRICT | E_ALL);

   date_default_timezone_set('Etc/UTC');

   $host = "mysql.xxxxxxxxxx.com.br"; // Host KingHost

   $usermysql = "XXXXXXXX"; // Mysql username
   $passmysql = "XXXXXXXX"; // Mysql password
   $db_name = "XXXXXXXX"; // Database name locaweb
   $admin_user = "XXXXXXXX"; // Administrative user

   require '../PHPMailerAutoload.php';

   $mail = new PHPMailer;

   $mail->isSMTP();
   $mail->Host = 'smtp.xxxxxxxxxx.net';
   $mail->SMTPAuth = true;
   $mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent, reduces SMTP overhead
   $mail->Port = 25;

   $mail->Username = 'contato@xxxxxxxxxxxxx.com.br';
   $mail->Password = 'cipava01';


   $mail->setFrom('contato@xxxxxxxxxxx.com.br', 'Espiriplug - Gestao de Bibliotecas Espiritas');
   $mail->Subject = "eSpiriplug - Boletim 021 - Lancamento BETA do Sistema de Gestao de Bibliotecas Espiritas";
   $mail->AltBody = 'Para ver a mensagem use um leitor de email compatível com HTML!';


   //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($host, $usermysql, $passmysql, $db_name);


   mysqli_select_db($mysql, 'mydb');

// Just for the test... ok!
//   $result = mysqli_query($mysql, "SELECT username , email , realname FROM forum_user WHERE substring(username,1,5)='teste'
//   OR   username ='eduardofuerte'");

   $result = mysqli_query($mysql, "SELECT username , email , realname FROM forum_user");

   foreach ($result as $row)
   { //This iterator syntax only works in PHP 5.4+

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

       $body = "<header>";
       $body = "<font face=Arial size=2>";
       $body = $body ."<p>";
       $body = "<b> Prezado(a) ".$row['username'] . "<b> </br>";
       $body = $body . "</br>";
       $body = $body . "</header>";
       $body = $body . file_get_contents('contents_espiriplug.html');

       //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


       if (!$mail->send())
       {
           echo "Mailer Error (" . str_replace("@", "&#64;", $row["email"]) . ') ' . $mail->ErrorInfo . '<br />';
           
           // Não parar de enviar.
           //break; //Abandon sending
           
           
       } else
       {
           echo "Message sent to :" . $row['username'] . ' (' . str_replace("@", "&#64;", $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']) . "'");
       }
       // Clear all addresses and attachments for next loop
       $mail->clearAddresses();
       $mail->clearAttachments();
   }

Open in new window


Thanks in advance!
SOLUTION
Avatar of Andy M
Andy M
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You can just add this line before to the addAddress call:
$mailer->ClearAllRecipients( );

Open in new window

Because now you sen email to all added address at any iteration.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You must also correct your code: when you build your $body you are continously overriding it. Use concatenation notation:
       $body = "<header>";
       $body .= "<font face=Arial size=2>";
       $body .= $body ."<p>";
       $body .= "<b> Prezado(a) ".$row['username'] . "<b> </br>";
       $body .= $body . "</br>";
       $body .= $body . "</header>";
       $body .= $body . file_get_contents('contents_espiriplug.html')

Open in new window

Avatar of Eduardo Fuerte

ASKER

Hi

Thanks for replies.

@Ray
It's a non profitable email sendings and very eventual - so I have to deal it by myself.

@Marco
I'm going to try your suggestions with a small number of emails each step.
@Eduardo,

It looks like you have copied the sample from the PHPMailer page - which is good.

The sample includes code to authenticate to SMTP - note this may not be necessary - your may server be configured to connect automatically for you. No harm in doing it this way though especially if you were having problems with mail before.

I would also consider using HEREDOC for your message construction - it will make your code easier to read and maintain.
@Marco

I couldn't  capture in what your last code differ from mine?
@Julian

What you post makes all sense.

The provider claims that the limit of "authenticated" emails sent was reached.... (at about 300 per hour)

So I can avoid to use smtp strategy, ok?

Could you possibly point how to workaround it (in code) ?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If you have another SMTP server you can log onto that does not have a limit then you can do so as you are doing. However, you might find the same problem - many ISP's impose limits on number of emails sent in a time period.

How many emails are you planning to send at a time?
Just about 750 in total ... so I can divide it during the day... (100 for hour f.e.)  so I can maintain SMTP.
I guess.
What triggers the emails being sent? Do they all go out at once in response to some event?
@Julian

I don't know if I well understood your question.

Accordingly to what I posted in my profile I'm working to real charity institutions interested in better organize themselves mainly here in Brazil, absolutely free of charges for them, this just during my free time.

I'm releasing a new software for libraries, something requested from time to time from some of them. So I'm advertising it by this mail!
What I meant was, what causes the email to be sent?

You said you have to send out 750 emails - do these all go out at in one go or do they get sent only when something happens.

How often are they sent.
Sorry!

These mails doesn't need to be sent at the same time or even during a short period of one day.

It can ben sent between a week or even a large period.
So you could have a server process that runs say every hour / day / whatever and processes the next N emails.

For instance a cron job kicks off a script that reads the next 100 unprocessed emails from the DB and sends them. The cron job can be scheduled to run far enough apart to keep the ISP happy.
@Marco
Thank you for the advises you gave me about my code corrections.

@Julian
Just to know.
The cron job to be scheduled  as you mentioned demands to be made at provider's Linux?  
(it seens very trick to be done)
@Marco

Just something that confused me, are you certain that without

$mail->ClearAllRecipients();

Open in new window


All the mails are sent at any interation?
Because PHPMailer example: mailing_list.php, where I obtained and adapted my code, doesn't use it.
You're right: I had not seen the last 2 lines within the loop
       $mail->clearAddresses();
       $mail->clearAttachments();

Open in new window

So you can ignore that comment (but keep the other about string concatenation as valid).

Julian suggested a good solution mentioning a CRON job.
I didn't  catched how to create a Linux CRON job, I have to learn about how to do it)

By now I'm sending it in a simpler way , in parts.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@Julian
I opened a ticket to my ISP snf soon I will have a reply about CRON.

@Ray
Really erratic. A friend received 04 email copies  I run the script just one time with all the complee user's table content and then the  browser "freezed".
After that ISP told me I reached the limit of emails/hour (300).
@Julian

The ISP replied me it's possible to schedule a CRON created by the user.

By the way, running the PHPMailer script - 100 mails each time, until ISP SMTP advices about emails limit per hour reached, stop a hour and then restart (since the email number is not so large, it's OK) everything seems to go fine, just one copy to each email address.
Thank you for everyone participation!
You are welcome.