2

I had time on another post to respond on time, sorry.

The purpose of the process is that after a definite time mails are sent to users of a website.

I have a cron that executes a php file at a specific time

For example, every Monday at 8:00 a.m.

* 8 ** 1 php-f / $ filepath ()

This php file sends thousands of emails but instead of sending all continuously from 8am, I want send 30 mails per minute from 8:00 eg

That is:

08:00 -> 0-30 mails

08:01 -> 30-60 mails

08:02 -> 60-90 mails ... etc.

Since launching the cron runs once at 8am I thought about using php sleep function to pause between minutes but does not Respect the command, the system fails and is locked. In my experiences with C the sleep function always work correctly.

I set the shipping to send 30 mails when and exit the loop with a counter

 ***** php-f /$filepath ()

and so force the system to run the file every minute.

My code

    $res = $admin->array_mixed(); //Array with all mails address

    $send_per_min=30;
    $send = 0;

    foreach ($res as $r){
    $mails->AddAddress("$r['invitacion_email']");
    .
    .
    .
    $mails = new PHPMailer(true);
$mails->Mailer = "smtp";
    .
    .
    .
    if($mails->Send()){                                      
    $send++;
    $log_OK .= $mail." Send!!! \n";
    }else{                              
    $log_KO .= $mail." Failed!!! \n";
    }


    if ($send == $send_per_min){//With this line I checked that after making 30 shipments out of the loop until the next minute the cron rerun
    //I want to replace it with a sleep that once sent 30 mails, wait until the next minute. In this way, you could set the cron at a specific time
    break;
    }

    }//End for

I hope you have been more clear than in the previous post (https://stackoverflow.com/questions/15393432/sending-emails-with-phpmailer-partitioned).

Greetings to the community.

Pd-Sorry for my bad English

Community
  • 1
  • 1
  • Maybe this could be helpful: http://stackoverflow.com/questions/45953/php-execute-a-background-process - I think you need to sort of fork the process so it can run in the background without blocking the main thread. It's just an idea, I'm not really familiar with that kind of processing, but it looks promising. Maybe you should give it a shot :) – Quasdunk Mar 14 '13 at 10:56

1 Answers1

0

You can call the php every 30 minute in cron, don't using sleep. If you wish can pass how parameter to PHP the quantity of mails to send. The PHP is executed and send all mails (only 30 or the quantity configured in database). After when a new call is executed from cron, you send more mails (only 30 or the quantity configured in database), and repeat again while you have mail to send. To this you can write in database or in a file the last e-mail sent (using the id or other control). To continue the send e-mail, but not resend e-mail repeated. The settings of sent and log you can write in SQLite, XML, text, MySQL or other.

you have only fill your $res with 30 mail not sent.

Only example:

SELECT 
    * 
FROM 
    `my_mail` m
WHERE 
    m.`isSent` = 'notsend'
LIMIT 30;

$res receive the return of SQL or your can format the return before, and every sent mail with no error

$log_OK .= $mail." Send!!! \n";

Write in database the information from sent with success.

Only example:

UPDATE
    `my_mail`
SET
    `isSent` = 'send'
WHERE 
    id = '$id';

Other solution below:

I create a class with one possible solution to your problem, the method "getMail" is your function to getMail, replace this function, the method "sentMail" is your function to sent mail by PHPMailer, the method "sentScheduleMail" is the engine from send every minute, but if the send mail is slower than 60 second the function will send mail only in next first minute.

<?php

class SentMailByPart {

    /**
     * SQL to recovery the quantity of mails specified
     * @param int $quantity
     */
    private function getMail($quantity) {
        return array(array("test1"), array("test2"));
    }

    /**
     * Function main to send mail
     */
    public function sentScheduleMail() {
        /**
         * While system is running
         */
        while (1) {
            /**
             * Time in unixtime
             */
            $res = $this->getMail(30);
            foreach ($res as $r) {
                // $this->sentMail($r);
                $this->sentMail($r);
            }
            unset($res, $r);
            $time = mktime();
            sleep($time % 60);
        }
    }

    /**
     * Settings of mail, subject and message (Your function to sent e-mail)
     * @param stdClass $settings
     */
    private function sentMail($r) {
        /**
         * New instance of PHP
         */
        $mails = new PHPMailer(true);
        /**
         * Mail address
         */
        $address = $r['invitacion_email'];
        /**
         * Sent by smtp
         */
        $mails->Mailer = "smtp";
        /**
         * Mail of destination
         */
        $mails->AddAddress($address);

        /**
         * Check mail is sent
         */
        if ($mails->Send()) {
            return true;
        } else {
            /**
             * Write error in error log
             */
            error_log(fprintf("Mail (%s) is not send. Erro: %s"
                            , $address
                            , $mails->ErrorInfo), 0);
            return false;
        }
    }

}

$sent = new SentMailByPart();
$sent->sentScheduleMail();

/**
 * if wish stop the send of mail alter $isRunning = 0, is run
 */
?>

Sorry if my english is very bad, my idioms is "pt-br".

Sileno Brito
  • 449
  • 1
  • 13
  • 31
  • cron every 30 minute: */30 * * * * php -qf .php – Sileno Brito Mar 14 '13 at 14:42
  • cron every 1 minute: */1 * * * * php -qf .php – Sileno Brito Mar 14 '13 at 15:55
  • But ... the web admin he wants to program a mailing at 8 and send all mails from the database (only 1 cron). So I need the sleep or similar, otherwise I have no control over cron. if the admin sets cron at 8:00 , the cron will run at 8:00, but at 8:01 will do nothing because it is set at 8:00 – Víctor Hdez Mar 14 '13 at 16:42
  • The way you treat him is based on run cron several times, but that's not the idea, the cron runs once. The idea of shipments per minute pause is to avoid saturating the mail servers and prevent the mail going to Spam folder Do you understand this explanation better? again, sorry my bad english – Víctor Hdez Mar 14 '13 at 16:53
  • I changed the solution, and add a new response at end. – Sileno Brito Mar 15 '13 at 15:49
  • thx Sileno, I will prove it. But the problem I had was that using sleep function, the system blocked. I will comment the progress – Víctor Hdez Mar 15 '13 at 17:21
  • You can run shell script or application? if is possible you can create one shell script to call your php using sleep or one C application to call your php to emulate a second cron. Other option is executing a recusive call, but the sleep is necessary to system no consume all recurse of the computer. In a call recursive, your call the script and execute, after the system call your php again. – Sileno Brito Mar 16 '13 at 13:11