2017-10-19 21 views
0

UPDATE:セットアップをテストした - それは動作します - 私のウェブホストは約6秒で600の電子メールを扱うことができない - 私が持っていた各接続は20秒待ってから、1通のメールを送って - それらのすべてがPHP複数のポスト要求

を経て私は600以上の電子メールでメーリングリストを持っています 私は600以上のメールを送信する機能を持っています

残念ながら、実行時間(90秒)には限界があります。完成されました。私はset_time_limit(0)で時間を変更することができません。私のウェブホストによって設定されているので(iniファイルでは変更できません)

私の解決策は、メインファイルからサブファイルに投稿要求をすることです。一度に100メールのチャンクを送信します。しかし、これらは遅滞なく送信されますか?または、次の要求を送信する前に回答を待つでしょうか?

コード:

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受信者
$startの総数iがSQL文

この(私は期待されるように)6つの並列接続を開始する開始行番号である - またはそれは(私が恐れているように)6つのプロセスをそれぞれ次々に始めるでしょうか?私が持っている受信スクリプトで

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

私は100%を確認していないが、6 procesesses – Tomm

+0

を開始しようとしているように見えるそれぞれ完了するために他のを待ちます - またはそれは同時になりますか? –

+0

私はその質問に私は確信していないと確信していない – Tomm

答えて

1

私は目的を達成することができる方法についていくつかのアイデアを提供します。

  1. 最初のオプション - curl_multi_*の機能を使用します。ノンブロッキングcURLリクエストを提供します。

    2。 2番目のオプション - amphpまたはReactPHPのような非同期ライブラリを使用します。基本的には、curl_multi_*、IIRCと同じ利点を提供します。

  2. pcntl_fork()を使用して、別々のプロセスを作成し、ワーカーノードと同様にジョブを配布します。

  3. pthreads拡張子を使用すると、実質的なマルチスレッドのユーザランドPHP実装が提供されます。

私は、並列処理の世界が;-)本当に厄介なことを証明することができ、いくつかの不気味な状況をアップしますので、最後の2つのオプションは、最後の手段でなければなりません、しかしあなたに警告します。

このようなアプリケーションを拡張する予定の場合は、外部サービスを使用するのが最善の方法です。

+0

PHPでのマルチタスクは難しくありません。 PHPは、私の答えに示されているように、stream_socket_client()を使ってマルチタスキングをOSに渡すことができます。 – Misunderstood

+0

私はそれが難しいとは決して言わなかった。私が言ったのは、並列処理の土地はすべてのミューテックスとロックで奇妙だということでした。 :-) – Ikari

1

100個のメールごとに1つずつ(または1つのスクリプトに値(0-5など)を渡す)6つのPHPスクリプトを作成します。
これらの6つのサブスクリプトを呼び出すメインスクリプトを作成します。

stream_socket_client()を使用してサブスクリプトを呼び出します。

6つのスクリプトが同時に実行されます。
サブスクリプトでエコーバックされたもの(ステータスなど)をキャッチすることができます。

$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); 
関連する問題