2017-10-19 21 views
0

MISE À JOUR: configuration testée - cela fonctionne - mais mon web-hôte ne peut pas gérer 600 email en 6 secondes environ - j'avais chaque connexion attendre 20 secondes puis envoyer un courrier - ceux sont tous passés parPHP demande multiple post

J'ai une liste de diffusion avec plus de 600 emails J'ai une fonction pour envoyer les 600+ emails

Malheureusement, il y a une limite quant au temps d'exécution (90 secondes) - et donc le script est arrêté avant est terminé. Je ne peux pas changer l'heure avec set_time_limit(0), car elle est définie par mon hébergeur (pas dans un fichier ini que je peux changer non plus)

Ma solution est de faire des demandes de post à partir d'un fichier principal vers un sous-fichier envoyer des morceaux de 100 mails à la fois. Mais seront-ils envoyés sans délai - ou attendront-ils une réponse avant d'envoyer la prochaine demande?

Le code:

for($i=0;$i<$mails;$i+100) { 
    $url = 'http://www.bedsteforaeldreforasyl.dk/siteadmin/php/sender.php'; 
    $myvars = 'start=' . $i . '&emne=' . $emne . '&besked=' . $besked; 

    $ch = curl_init($url); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $myvars); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_SAFE_UPLOAD, 0); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 1); 

    $response = curl_exec($ch); 
    curl_close($ch); 
} 

$mails est le nombre total de bénéficiaires
$start est le numéro de la ligne de départ i l'instruction SQL

Est-ce que ce (comme je l'espère) commencer à 6 connexions parallèles - ou est-ce que (comme je le crains) commencer 6 procès l'un après l'autre?

Dans le script de réception J'ai:

<br> 
ignore_user_abort(true);<br> 
$q1 = "SELECT * FROM maillist LIMIT $start,100 ORDER BY navn"; 
+0

Je ne suis pas sûr à 100% mais il semble que ça va commencer 6 procesesses – Tomm

+0

Est-ce que chaque attendre l'autre pour compléter - ou il sera en même temps? –

+0

Je n'ose pas répondre à cette question Je ne suis pas certain – Tomm

Répondre

1

Je vais vous donner quelques idées sur la façon d'atteindre l'objectif.

  1. Première option - Utilisez la suite de fonctions curl_multi_*. Il fournit des requêtes cURL non bloquantes.

    2. Deuxième option - Utilisez une bibliothèque asynchrone comme amphp ou ReactPHP. Bien qu'il fournirait essentiellement le même avantage que curl_multi_*, IIRC.

  2. Utilisez pcntl_fork() pour créer des processus distincts et distribuer le travail comme dans les nœuds de travail.

  3. Utilisez l'extension pthreads, qui fournit essentiellement une implémentation PHP utilisateur de véritable multithreading.

Je vous préviens cependant, les deux dernières options devraient être le dernier recours, puisque le monde de traitement parallèle est quelques situations fantasmagoriques qui peuvent se révéler être vraiment embêtant ;-).

Je vous suggérerais probablement aussi que si vous envisagez de mettre à l'échelle ce type d'application, il serait préférable d'utiliser un service externe.

+0

Multi-tâches en PHP ne doit pas être difficile. PHP peut passer le travail multitâche au système d'exploitation en utilisant stream_socket_client() comme indiqué dans ma réponse. – Misunderstood

+0

Je n'ai jamais dit que c'était difficile. Tout ce que j'ai dit, c'est que la terre du traitement parallèle est étrange avec tous les Mutex et les Locks. :-) – Ikari

1

Créez six scripts PHP, un pour 100 courriels (ou transmettez une valeur (par exemple 0 à 5) à un seul script).
Créez un script principal pour appeler ces six sous-scripts.

Utilisez stream_socket_client() pour appeler les sous-scripts.

Les six scripts s'exécuteront simultanément.
Vous pouvez intercepter tout ce qui est renvoyé par les sous-scripts (par exemple, état).

$timeout = 120; 
$buffer_size = 8192; 
$result = array(); 
$sockets = array(); 
$id = 0;  
header('Content-Type: text/plain; charset=utf-8'); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail1.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail2.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail3.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail4.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail5.php"); 
$urls[] = array('host' => 'www.example.com','path' => "http://www.example.com/mail6.php"); 
foreach($urls as $path){ 
    $host = $path['host']; 
    $path = $path['path']; 
    $http = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n"; 
    $stream = stream_socket_client("$host:80", $errno,$errstr, 120,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); 
    if ($stream) { 
    $sockets[] = $stream; // supports multiple sockets 
    fwrite($stream, $http); 
    } 
    else { 
    $err .= "$id Failed<br>\n"; 
    } 
} 
echo $err; 

while (count($sockets)) { 
    $read = $sockets; 
    stream_select($read, $write = NULL, $except = NULL, $timeout); 
    if (count($read)) { 
    foreach ($read as $r) { 
     $id = array_search($r, $sockets); 
     $data = fread($r, $buffer_size); 
     if (strlen($data) == 0) { 
    // echo "$id Closed: " . date('h:i:s') . "\n\n\n"; 
     $closed[$id] = microtime(true); 
     fclose($r); 
     unset($sockets[$id]); 
     } 
     else { 
     $result[$id] .= $data; 
     } 
    } 
    } 
    else { 
// echo 'Timeout: ' . date('h:i:s') . "\n\n\n"; 
    break; 
    } 
} 
var_export($result);