PHP Verständnisfrage und Mailversand in einer Schleife begrenzt

overflow

Member of Honour
Erstmal zeige ich euch lieber meine Dateien:

Dateien:
mail.txt- 12x ist meine E-Mail eingetragen
Code:
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
overflow@nomail.com
mail.php - mail.txt wird geöffnet und die E-Mail-Adresse übernommen mit einem Warteintervall von 10 Sekunden zwischen jedem Sendevorgang
PHP:
<?php

$datei = fopen("mail.txt","r");

$sender = "overflow@nomail.com";
$betreff = "Test";

$mailtext = "Hallo,\n";
$mailtext.="Habo"

while(!feof($datei))
   {
   $empfaenger = fgets($datei,60);
   mail($empfaenger, $betreff, $mailtext, "From: $sender");
   sleep( 10 );
}

fclose($datei);

?>

Fragen - Thema 1:

Wenn ich die mail.php ausführe, ist der Browser ständig am arbeiten/warten bis der Prozess komplett fertig ist. Jedoch bricht er den Vorgang bei etwa 6-7 E-Mails ab.
- Wieso ist das so?
- Ist es ein Schutz von meinem Webhoster (Strato)?

Fragen - Thema 2:
Gibt es eine elegantere Möglichkeit in PHP?
Habe an eine Variante in Kombination mit Ajax gedacht, nach jedem Erfolgreichen Versand, wird es auf dem Browser angezeigt.
 
Zu Frage 1: PHP hat einen Konfigurationswert, der sich max_execution_time nennt. Nach erreichen des dort konfigurierten Werts (üblicherweise ca. 10-30s) wird ein Skript abgebrochen. Für Massenmailer ist PHP daher nur bedingt geeignet und es muss mit entsprechenden Threads gearbeitet werden, die jedes Mal beendet werden, wenn eine Email versendet wurde.
 
Die Forumsoftware hier sowie andere bieten über die Administrationsfläche die Möglichkeit "An alle Mitglieder" eine E-Mails zu senden.

Arbeiten diese auch mit Threads ?
Ich erinnere mich nämlich an ein Programm, welches angezeigt hat ob die Mail raus ist ala:" Mail 1 ist raus, Mail 2 ist raus usw."
 
http://php.net/manual/de/function.set-time-limit.php

mit
PHP:
<?php
set_time_limit(0);
?>
wird das Timeout abgeschalten. Ausnahme natürlich, die Funktion ist vom Hoster geblockt oder es gibt außer dieser Beschränkung weitere Zeit-Beschränkungen z.B. wenn PHP via Apache-Modul mod_fcgid + suEXEC eingebunden ist (da gibt es z.B. eine Option IPCCommTimeout, welche sich nicht script-seitig manipulieren lässt)
 
@beavisbee: Nette Funktion, leider nicht möglich bei Strato-Servern.

Zum Thema "Threads in PHP" spucken die Suchmaschinen leider nichts informatives aus.
Konnte keine Einführungen auf Deutsch finden.
Auch in meinen PHP Büchern steht nichts drin.
 
Lies dir doch einfach den aktuellen wert von max_execution_time aus, schick dann ein paar Mails raus, lade die Seite neu und schick die nächsten Mails raus. Das machst du solange, bis alle Mails raus sind.
Die "Ausgabe im Browser" kannst du mit ob_flush() erzwingen.
 
Zum Thema "Threads in PHP" spucken die Suchmaschinen leider nichts informatives aus.
Konnte keine Einführungen auf Deutsch finden.

Deutsch nicht, allerdings: http://blog.motane.lu/2009/01/02/multithreading-in-php/

you don’t extend the Thread class, you simply provide the name of a callback function in the constructor.
Habs persönlich nicht ausprobiert, es dürfte allerdings funktionieren.. Da deine Threads
soweit ich dein Problem verstehe nicht konkurierend sind, dürfte ein einfaches Aufrufen von child processes bereits reichen.

http://ch.php.net/manual/en/function.pcntl-fork.php

Da les ich gerade..:

Process Control support in PHP is not enabled by default. You have to compile the CGI or CLI version of PHP with --enable-pcntl configuration option when compiling PHP to enable Process Control support.
Folglich musst du Glück haben. Einfach mal testen. :)
.. Hmm und dann noch:

Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.

Das heisst wohl: Bad Luck. :)

JFYI
 
Thunderb0lt war so lieb mir zu helfen und ein geniales Skript zu erstellen.
Dieses möchte ich mit seiner Einverständnis hier veröffentlichen.
Viel brauchen wir dazu nicht sagen.

PHP:
 <?php

$start = time();

$max_exec = ini_get('max_execution_time');

// Reads entire file into an array
$lines = file("mail.txt");

$offset = 0;

$sender = "overflow@nomail.com";
$betreff = "Test";

$mailtext = "Hallo,\n";
$mailtext .= "Habo";

if(isset($_GET['offset']) && intval($_GET['offset']) > 0)
{
    $offset = intval($_GET['offset']);
}

$lineCnt = count($lines);
for($i=$offset; $i<$lineCnt; ++$i)
{
    if( (time() - $start) > ($max_exec-10) )
    {
        echo '<SCRIPT LANGUAGE="JavaScript">
              <!--
              location="' . $_SERVER['PHP_SELF'] . '?offset=' . $i . '";
              //-->
              </SCRIPT>';

        exit();
    }

    #mail($lines[$i], $betreff, $mailtext, "From: $sender");
    echo $lines[$i];
    sleep(5);
}

echo 'All mails sent';

?>
 
Hallo,

lies dir bitte folgendes zu der php mail() Funktion durch:
Note:

It is worth noting that the mail() function is not suitable for larger volumes of email in a loop. This function opens and closes an SMTP socket for each email, which is not very efficient.

For the sending of large amounts of email, see the » PEAR::Mail, and » PEAR::Mail_Queue packages.
Quelle (fast direkt über den Kommentaren)

lg
 
Zurück
Oben