Mehrfache Skriptausführung

mtk-flo

Erfahrenes Mitglied
Hallo,

ich habe folgendes Problem:

ich versende eine Menge an Emails an ausgewählte Personen (die auch die Email bekommen möchte).
Jedoch bricht das Script nach eine Zeit ab.

Wie kann ich das Skript mehrfach aufrufen, damit ich die max_execution_time umgehe und das Skript alle Emails versendet?
Ich würde gerne einrichten, dass ich immer 50 Personen eine Email schicke und anschließend, das Skript neu geladen wird und die nächsten 50 Emails verschickt werden.
Das ganze halt so lange, bis alle Emails raus sind.

Vielen Dank schon mal
mtk-flo
 
Da gibt es mehrere Möglichkeiten.

  1. Die einfachste ist du setzt die Ausführungszeit für ein Script einfach höher was aber keine schöne Lösung ist.
  2. Du erstellst dir einen Cron-Job der in einer bestimmten Zeit die Datei aufruft und in einer Datenbank vermerkst du dir, an wen du schon eMails verschickt hast, damit sie nicht doppelt versendet werden.
  3. Du erstellt dir eine Classe die sich immer wieder selber aufruft, das hilft auch in vielen Fällen. Das machst du solange bis deine ganzen Mails verschickt wurden.

Gruß Dennis
 
Leider kann ich die max_execution_time nicht erhöhen.
Dies ist leider von Strato so vorgegeben.

Das mit den Cronjobs betreibe ich im Moment, was ich allerdings nicht als Lösung ansehe, sondern nur als Übergangslösung.

Das mit der Klasse habe ich nicht recht verstanden.
Ungefähr so !?

> Funktion
--> erstellt eine Instanz
--> ruft eine Methode auf (sende 50 Emails)
--> am Ende der Methode erstelle ich dann eine neue Instanz?
----> über die neue instanz wird wieder die Methode (sende 50 Emails) aufgerufen!?

Hat jemand ein Code beispiel dafür?
Das Skript läuft dadurch aber weiterhin lange, ich rufe ja mehrere Klassen innerhalb eines Skriptes auf und nicht das Skript an sich neu, oder?!
 
  1. Du erstellt dir eine Classe die sich immer wieder selber aufruft, das hilft auch in vielen Fällen. Das machst du solange bis deine ganzen Mails verschickt wurden.

Na ob das Hilft,
der Server schaut ja nur wielange ein Script ausgeführt wird und nicht wielange eine Klasse "ausgeführt" (wobei ja Klassen nicht "ausgeführt" werden) wird.
Du schreibst ein Script, dass immer x Emails versendet, nen Location-Header schickt oder einen Meta-Refresh mit einer Schritt-GET-Variablen auf sich selber ausführt. Wenn alles verschickt -> kein Refresh.


PS: habe auch immer so ein Problem gehabt, nur nicht mit Emails, sondern mit so anderen Zeugs. Das Script musste insgesamt vielleicht 10min durchlaufen, ging natürlich auf nem billig Webspace nicht. Habe mir ein AJAX-Gerüst gebaut, dass Scripte ausführt und immer ein Schritt weitergeht, bis eben die Nachricht vom Script kommt, dass er fertig ist.
 
Zuletzt bearbeitet:
Na ob das Hilft,
der Server schaut ja nur wielange ein Script ausgeführt wird und nicht wielange eine Klasse "ausgeführt" (wobei ja Klassen nicht "ausgeführt" werden) wird.
Du schreibst ein Script, dass immer x Emails versendet, nen Location-Header schickt oder einen Meta-Refresh mit einer Schritt-GET-Variablen auf sich selber ausführt. Wenn alles verschickt -> kein Refresh..

Es wird zwar schon geschaut wie lange das Script arbeitet aber er kann auch nebenbei Ausgaben machen und wenn ich mich recht erinnere dann wird ein Script erst abgebrochen wenn es zu viele Ausgaben in zu kurzer Zeit macht oder wenn es zu lange dauert bis eine Ausgabe erfolgt.
Jedenfalls hat das bei meinen Scripts immer gereicht und die laufen auch ab und zu 50 Minuten oder so. Eine XML Struktur zu erstellen und dann noch einen FTP upload zu machen ist halt auch Zeitaufwändig. ;-)

Einfach mal ausprobieren.

PHP:
class test {
     private $max;

     public __constructor($max_mails){
          $this->max = max_mails;
     }

     public send($from_is, $to_id){
          ... senden ...
          print("Gesendet ID: ".$id);
     }
}

$senden_pro_execute = 30;
for(int i = 1; i < 10; i++){
     $send = new test($senden_pro_execute);
     $send->send(i*$senden_pro_execute, i*$senden_pro_execute+$senden_pro_execute);
}

So hätte ich das in etwa gemacht....
 
Habe nun mal folgendes zusammen gebaut...

Meine Klasse:
PHP:
	class CEmails {
		private $maxKunden = 0;
		private $sendeVon = 0;
		private $sendeAnzahl = 0;
		
		public function CEmails($_maxKunden) { 
			$this->maxKunden = $_maxKunden;
		}
		
		public function sendeEmails($von, $anzahl = 30) {
			$this->sendeVon = $von;
			$this->sendeAnzahl = $anzahl;
			
			if($this->maxKunden >= $this->sendeVon)
				$this->sendNow();
		}
		
		private function sendNow() {
			 $db_kunde = new CDatenbank();
			 $db_kunde->open();
			 $db_kunde->execute("SELECT * FROM kunde LIMIT ".$this->sendeVon.", ".$this->sendeAnzahl.";");
			 while($kunde_row = $db_kunde->fetch()) {

			 	// ... bereite Emails vor und sende die Emails

			 } // while($kunde_row = $db_kunde->fetch())			
		}
	}

Mein Aufruf:
PHP:
include_once("klassen/CEmails.php");
include_once("klassen/CDatenbank.php");

$db_emails = new CDatenbank();
$db_emails->open();

$db_emails->execute("SELECT * FROM kunde");
$kundenAnzahl = $db->zeilenAnzahl;

for($i = 0; $i < $kundenAnzahl; $i+= 30) { 
	$send = new CEmails($kundenAnzahl);
	$send->sendeEmails($i, 30);
}

Jedoch bekomm ich einen Fehler: Internal Server Error
Was ja bedeutet, dass ich eine Zeitüberschreibung bekommen habe...

Was hab ich falsch gemacht?
 
Zuletzt bearbeitet:
Mach es doch einfach mit nem Meta Refresh:

PHP:
<?php
	
	$seite		= empty($_GET["s"]) ? 1:$_GET["s"];	// in die sql mit limit etc
	$schritt 	= 50; 													// in die sql mit limit etc
	while( blabla ) {
		mail( blabla );
		$schritt--;
	}
	
	if( $schritt==0 ) {
		echo '<meta http-equiv="refresh" content="1; url=script.php?s='.($seite+1).'">  ';
	} else {
		echo 'fertisch';
	}

?>

Wenn du irgendwas mitzählen willst oder so, dann mach es per Session. Fertig ist's.
 
Ja werde ich dann auch mal ausprobieren,
aber gefallen tut mir die Lösung mit dem META-Refresh nicht...
Ist nicht elegant und nur ein weiterer Work-Around (ähnlich wie meine Cronjob Lösung)
 
Ja werde ich dann auch mal ausprobieren,
aber gefallen tut mir die Lösung mit dem META-Refresh nicht...
Ist nicht elegant und nur ein weiterer Work-Around (ähnlich wie meine Cronjob Lösung)

Eine "nicht-Work-Around"-Lösung wirst du aber wohl kaum hinkriegen, solange du die php.ini nicht bearbeiten kannst. Ist dir ja hoffentlich klar? Diese Methode mit dem AJAX - Aufruf finde ich persönlich perfekt. Habe in meinem Script auch sowas eingebaut, dass er es sagen wir mit 50 Datensätzen probiert -> wenn timeout -> das selbe mit 40 Datensätzen -> wenn geklappt, dann die nächsten 40 Datensätze, wenn nicht -> 30 Datensätze probieren.

Finde ich persönlich sehr angenehm. Man kriegt keine dämlichen Refreshes, hat eine schöne "Wird bearbeitet" Anzeige und alles auf einem Fleck.

Gruß
 
Zurück