27. august 2003 - 13:01Der er
34 kommentarer og 1 løsning
"Maximum execution time"-error ved afsendelse af email med Zend
Jeg afsender emails ved brug af http://www.zend.com/codex.php?id=347&single=1 , adresserne hentes fra database (ca. 2000 stk.) men jeg får efter 30 sek. fejlen: Fatal error: Maximum execution time of 30 seconds exceeded . Det kører hos Wannafinds server og de kan ikke ændre de 30 sek. . Hvad gør jeg?
I dette særtema ser vi på, hvordan cloud og AI bliver fundamentet for virksomhedernes digitale forretning, og hvordan de nye muligheder for automatisering og forretningsværdi kan udnyttes uden at miste overblik, sikkerhed og menneskelig kontrol.
Hvis php ikke kører i safe_mode kan du prøve: set_time_limit(0); Fjerner 30 sek. grænsen.
Hvis du ikke har lov til at køre denne funktion er du nødt til at dele dine email-adresser op. Du kan f.eks. kalde dit sende-script i et antal iframes, hvor der ved hvert kald f.eks. sendes 500 emails.
Synes godt om
Slettet bruger
27. august 2003 - 13:14#3
Jeg bruger flg. kode (udpluk): // Etablerer forbindelse til databasen via filen dbconnect.php include('connect/dbconnect.php');
// Data hentes fra database $res = mysql_query("SELECT email FROM tbl_customer") or die (mysql_error());
$from = "Kontor@fuglebjerggaard.dk"; //din egen mail :-) $header = "Content-type: text/html; charset=iso-8859-1"; $subject = "Nyhedsbrev fra Fuglebjerggaard $date"; $body = "<html> <head> </head>... ... </html>";
Det er stadig en "grim" løsning da scriptet køres på et webhotel som deles med mange andre - det er hård belastning af serveren i lang tid - det bør man (synes jeg) ikke gøre...
Synes godt om
Slettet bruger
27. august 2003 - 14:34#8
Men hvad gør jeg så? Jeg skal altså sende en ca. 500 afsted ad gangen, men hvordan?
Jeg vil foreslå, at du sætter et "flag" altså en parameter der kan være sand eller falsk og indikerer om der er udsendt email til personen eller ej.
Og så gør du noget i retning af:
SELECT * FROM tabel WHERE NOT emailsent ORDER BY id ASC LIMIT 0, 200 loop over de valgte poster { blablaba email... } UPDATE tabel SET emailsent=true WHERE NOT emailsent ORDER BY id ASC LIMIT 0, 200
-den kører du så nogle gange til alle personer har fået sendt emails
Inden du sætter scriptet i gang næste gang, skal du så lige sørge for at nulstille emailsent kolonnen!
Synes godt om
Slettet bruger
28. august 2003 - 10:27#10
Jeg har fået flg. til at virke, dog bliver den ved med at sende mails idet den sidste sql ikke virker (sætter ikke 'ok' ind!) Nogen idé om hvorfor?
... $res = mysql_query("SELECT email FROM tbl_customer_tmp WHERE emailsent <> 'ok' ORDER BY id ASC LIMIT 0, 2") or die (mysql_error());
$sql="UPDATE tbl_customer_tmp SET emailsent = 'ok' WHERE emailsent <> 'ok' ORDER BY id ASC LIMIT 0, 2"; $result = mysql_query($sql) or die (mysql_error()); //indsæt pause/wait på 10-15 sekunder, så serveren ikke belastes hårdt og vedvarende - giv lidt til andre processer. header("Location:sammeside.php");
Synes godt om
Slettet bruger
28. august 2003 - 11:41#12
God idé med et wait! Den bliver ved med at brokke sig over ORDER BY id ASC i den sidste sql. Skal det med? eller kan jeg bare skrive $sql="UPDATE tbl_customer_tmp SET emailsent = 'ok' WHERE emailsent <> 'ok' LIMIT 2"; fordi det virker nemlig (jeg ved bare ikke om det er helt korrekt!?)
Synes godt om
Slettet bruger
28. august 2003 - 11:57#13
Dette er min kode nu - den udskriver dog "Det var det!" uden at sende nogle emails:
$res = mysql_query("SELECT email FROM tbl_customer_tmp WHERE emailsent <> 'ok' ORDER BY id ASC LIMIT 0, 2") or die (mysql_error());
$mysql_result=mysql_query($res);
$num_rows=@mysql_num_rows($mysql_result); if ( $num_rows == 0 ) {
Alternativ (Du har ikke fået alle rettelser med fra sidste alternativ - de kommer her igen):
$numemails = 100; $limitid = isset($_GET['limitid']) ? $_GET['limitid'] : $numemails; $res = mysql_query("SELECT email FROM tbl_customer_tmp WHERE emailsent <> 'ok' AND id < $limitid") or die (mysql_error()); if (mysql_num_rows($res) > 0) { $smtp = new smtp_client; $smtp -> smtp_client(); while (list($email) = mysql_fetch_row($res)) { $smtp->email($from, $email, $email, $header, $subject, $body); } $smtp->send(); $sql="UPDATE tbl_customer_tmp SET emailsent = 'ok' WHERE emailsent != 'ok' AND id < $limitid"; $res = mysql_query($sql) or die (mysql_error()); //indsæt pause/wait på 10-15 sekunder, så serveren ikke belastes hårdt og vedvarende - giv lidt plads til andre processer. header("Location:sammeside.php?" . ($limitid + $numemails)); exit; } else { echo "Jeg tror jeg er færdig for denne gang..."; exit; }
Det vil forøvrigt være hurtigere, hvis emailsent er en tinyint-kolonne og du benytter 0 og 1 til at angive sandt/falsk - dermed kan du bare skrive "WHERE NOT emailsent" i din query - det er hurtigere!
Det er fordi du ikke bruger mit alternativ... - i stedet for at smide mine rettelser ind i din kode så prøv at smid din kode ind i mit alternativ :-) (Find 5 fejl ;-))
Bare sammenlign din og min udgave og find de ting du har glemt/overset.
Synes godt om
Slettet bruger
28. august 2003 - 13:24#23
Jeg kan f... ikke se det!?
Synes godt om
Slettet bruger
28. august 2003 - 13:25#24
er det limitid der skal være lig med det antal der skal sendes pr gang?
Synes godt om
Slettet bruger
28. august 2003 - 13:32#25
Jeg giver snart op - Jeg kan ikke se hvad det er fra min kode som jeg skal sætte ind i din!?
Synes godt om
Slettet bruger
28. august 2003 - 13:33#26
Men kan du ikke så give fortælle mig om min kode kan bruges i stedet for dit alternativ - for så må jeg nøjes med en (det virkede nemlig umiddelbart fint)
Du er bare super! Det virker fint nu og jeg har også fået tilføjet den detalje som tømmer emailsent igen efter afsendelse af dem alle - Så meget stort tak skal du have!!! :-)
Jeg har modtaget mail fra jlyngso og indholdet følger her for evt. interesserede:
27. og 28. august hjalp du mig med at få php til at afsende emails til en stor mængde adresser ved brug af Zend ( http://www.eksperten.dk/spm/393199 ). Vi endte op med at få det hele til at virke.
Jeg er dog ved afsendelse af emails'ne stødt på et lidt mærkeligt problem: Efter at have stået og afsendt 10 emails ad gangen med 25 sek. pause afbrydes det hele efter ca. 3 min. med: Action canceled Internet Explorer was unable to link to the Web page you requested..
I starten afsendte jeg 50 emails med 5 sek. pause og derefter 25 emails med 10 sek. pause, men begge gange afbrød den efter et par minutter med "Fatal error: Maximum execution time of 30 seconds exceeded...". Jeg kontaktede webhotellet (Wannafind) og efter deres anbefaling ændrede jeg antal emails og pause til ovenstående (10 emails / 25 sek. ), men fik altså efter nogle minutter (i databasen kan jeg se at den nåede til ca. nummer 400) ovenstående fejl. Det virker på mig helt utroligt hvis Wannafinds smtp-server ikke skal kunne sende 10 emails afsted ad gangen!?
1. Du har en grænse på 30 sek. for hvor lang tid et script må tage at eksekvere - de 30 sek. dækker både den pause du sætter ind samt tiden for at udføre div. kode - blandt andet afsendelse af x antal emails! 2. Du har en grænse derhjemme på din Internet Explorer der ikke tror at skidtet fungerer fordi det tager så lang tid at hente og der kommer ikke noget output.
Jo længere pause du indsætter jo bedre for serveren men desto dårligere for IE - dvs. der skal så vidt muligt findes en kompromis løsning som tilfredsstiller begge kriterier!
Det bør ikke tage lang tid at afsende disse mails og jeg tvivler på, at det er SMTP serveren der giver problemer.
Derudover tager det noget tid at koble op til mysql-basen og eksekvere dine mysql-statements, så det kan ikke betale sig at sende for små mængder post af gangen!
Jeg vil gerne have respons på pkt. 1-6 ovenfor og høre om resultaterne - både mht. opfyldelse af pkt. 1 og pkt. 2!
Synes godt om
Slettet bruger
30. august 2003 - 12:32#31
Tak for hjælpen!
Jeg har med succes afsendt 900 emails (til mig selv som test) med både kombination 5. og 6.. Da der endes op med at skulle afsendes over 2000 emails tror jeg at kombination 6. vil være at foretrække.
Er det ikke muligt at udskrive f.eks. teksten "Emails afsendes!" hver gang siden loades, for på den måde at undgå at IE kommer med "Kan ikke finde siden..."?
så kan du ikke lave header() - det kan ikke kombineres med html-output!
Men du kan måske lave et eller andet redirect efter x antal sekunder - altså i stedet for pausen... - det kan stensikkert laves som meta-tag, men jeg mener også jeg har set det i et alm. php header-kald
Med method II kan du sagtens lave output til browseren - bare du placerer header-kaldet inden dit output!
Eksempelvis:
Email 1-500 sendt med succes! -Fortsætter om 10 sekunder med næste batch!
(dvs. skrot dit sleep() kald!)
Synes godt om
Slettet bruger
30. august 2003 - 13:27#35
Flg. virker perfekt:
header( 'refresh: 10; url=sammeside.php?limitid=' . ($limitid + $numemails)); echo '200 emails afsendt - Sender næste 200 om 10 sekunder...';
Nu er problemet vist løst - også selvom der skal afsendes mange flere emails...
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.