PHP execution times out after 60 seconds

I have a script which sends reminder e-mails to members of an organisation if they have failed to renew their membership (all memberships are renewable in November). First the script selects e-mail addresses from a MySQL database, then it sets about e-mailing each member (about 100).

The script works perfectly with a small test data set, but times out with the real set. I get the following PHP error message:

Fatal error: Maximum execution time of 60 seconds exceeded in D:\websites\hmicom\ est\findlatepayers.php on line 41.
Here’s part of my code:

if ($result && mysqli_num_rows($result) > 0) {
        while ($row = mysqli_fetch_array($result)) {
            $bus_id = $row['bus_id'];
            $bus_name = $row['bus_name'];
            $id = $row['member_index'];
            $subject = "Holiday Mull renewal 2011: " . $bus_name;
            $query2 = "SELECT first_name, last_name, email FROM members WHERE member_id = $id";
            $result2 = mysqli_query($link, $query2);
            if ($result2 && mysqli_num_rows($result2) > 0) {
                $row2 = mysqli_fetch_array($result2);
                $email = $row2[2];
                $emails[] = $row2[0]. ' '. $row2[1] . ', '. $row2[2] . '<br />';
                $message = "Dear " . $row2[0] . " " . $row2[1] . ",\\r\
\\r\
" . $content;
                if ($email && $subject && $message && $headers){
                    mail ($email, $subject, $message, $headers);
                    $mails++;
                }
            }
        }
    echo $mails . " e-mails sent<br />";
    echo $message;
    }

Line 41 is the ‘$mails++’, so it looks as if it’s the mailing that’s taking up the time. The penultimate line of code should print out the addresses used, but because execution failed I don’t actually know how many e-mails were sent (if any). However, I can rectify that myself.

My problem is I don’t know which of several possible timeouts I need to increase, and I don’t want to annoy members by repeated attempts to mail them all. Any suggestions, please ?

That looks pretty nasty, you are creating a loop which in a) queries the database and then b) sends an email.

Do operation a) first and just collect up all the name, biz, email addresses into an multi array.


$send[0]['name'] = "Mr Scott" ;
$send[0]['biz'] = "My Little Haggis" ;
$send[0]['email'] = "blah@haggis.com" ;

$send[1]['name'] = "Mrs Whisky" ;
$send[1]['biz'] = "WhiskyRUs" ;
$send[1]['email'] = "bloop@whisky.com" ;


Then loop through that array sending the email and at the same time echoing out the email address so you can see exactly how far your script got.



$subject = "Declare it once, here" ;

foreach( $send as $key => $value ){

echo 'Sending email to '. $value['name'] . '<br />' ;
// when you are finally sure it works
// do your mail() here

}



Thank you, Cups. I’m sure that would be a better way to do it, and I’ll change my code for next time. However, looping through the database isn’t what’s taking up the time. If I comment out the ‘mail’ it’s pretty instantaneous.

Meanwhile I need to get these messages sent, so an increase in the timeout, until I can sort out my code, would be handy.

I think the problem is worsened because PHP has to cease its connection to the database, send mail, then reconnect - although I am not entirely sure about this.

look at ini_set() if you just want to override the max timeout for this one script, use ini_set() at the top of your script.

http://www.php.net/manual/en/ini.list.php

max_execution_time is the one I think you want. edited -> sb max_execution_time

I’d set the email address to my own address whilst sorting this out, save getting on peoples nerves.

Thanks again. It’ll be interesting to see what happens if I e-mail myself 100 times !

Hello Cups, Thanks again for your help. I’m in the clear now.

I put

set_time_limit(0);

at the top of my script, which has the effect of preventing timeout altogether (probably not wise, but I had previously tested the script for infinite loops). And it worked perfectly.

With default timeout (60 secs) it was sending 35 messages, so I was able to establish approximately where it failed last night, and send from there today. I can accept the odd omission or double sending.

PHP’s ‘mail’ function is fairly basic, and I wonder if it sends each mail before continuing the script (rather than creating a buffer). I’m running the script locally, and my upload speed isn’t all that great.

Just change the subject to “alter-ego” and then create an email rule to siphon them off into a folder. :lol:

Yes, I did something like that. I was more meaning that my ISP might treat it as spam, coming FROM my address, but they didn’t.

I’m working on a version using your approach. It will be interesting to see what effect that has on the execution time.

Thats just reminded me, I spotted this fakemail ages ago - but have never had to use it.

Comes in Python or Perl flavours though - might be overkill for your app at the mo, one for the future maybe?

Thanks. It looks interesting, although possibly overkill right now. I’ve had to test a member login process, but I’ve managed so far to do this on my local server, sending mails addressed to me out into the wider world, returning via my broadband ISP. The weakness is I have to log in as myself, or modify the script for test purposes when I want to pretend to be someone else (logging in using some else’s login name (=e-mail address).

Thanks for your help. I’ve been able to send reminder messages to all our delinquent members, and they are replying.