【问题标题】:PHP multiple post requestPHP 多个 post 请求
【发布时间】:2017-10-19 07:43:12
【问题描述】:

更新:安装测试 - 它工作 - 但我的网络主机无法在大约 6 秒内处理 600 封电子邮件 - 我让每个连接等待 20 秒然后发送一封邮件 - 这些都通过了

我有一个包含 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是SQL语句的起始行号

这会(如我所愿)启动 6 个并行连接 - 还是(如我所惧)会一个接一个地启动 6 个进程?

在接收脚本中我有:

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

【问题讨论】:

  • 我不是 100% 确定,但看起来它将开始 6 个进程
  • 是否会等待对方完成 - 还是同时进行?
  • 我不敢回答这个我不确定的问题
  • 我认为 curl_exec 是阻塞的,所以这将按顺序运行。也许 multi-exec 会帮助php.net/manual/en/function.curl-multi-exec.php
  • curl_exec 正在阻塞,我想知道的是:即使您设法使用 multi-exec 在 1/6 的时间内发送所有邮件,这真的是理想的行为吗?在不到 90 秒的时间内发送了 600 多封邮件是很多...

标签: php email curl post


【解决方案1】:

创建六个 php 脚本,每 100 封电子邮件一个(或将值(例如 0-5)传递给单个脚本)。
创建一个主脚本来调用这六个子脚本。

使用stream_socket_client() 调用子脚本。

这六个脚本将同时运行。
您可以捕获子脚本回显的任何内容(例如状态)。

$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);

【讨论】:

    【解决方案2】:

    我将提供一些关于如何实现目标的想法。

    1. 第一个选项 - 使用 curl_multi_* 函数套件。它提供非阻塞 cURL 请求。

      2 。第二个选项 - 使用像 amphpReactPHP 这样的异步库。虽然它本质上会提供与 curl_multi_*, IIRC 相同的好处。

    2. 使用pcntl_fork() 创建单独的进程并像在工作节点中一样分配作业。

    3. 使用pthreads 扩展,它本质上提供了真正多线程的用户态PHP 实现。

    我会警告你,最后两个选项应该是最后的手段,因为并行处理世界会出现一些令人毛骨悚然的情况,这可能会被证明是非常讨厌的 ;-)。

    我也可能会建议您,如果您打算扩展此类应用程序,最好使用一些外部服务。

    【讨论】:

    • PHP 中的多任务处理并不难。 PHP 可以使用 stream_socket_client() 将多任务工作传递给操作系统,如我的回答所示。
    • 我从未说过这很困难。我所说的只是并行处理的领域充满了所有互斥锁和锁。 :-)
    猜你喜欢
    • 1970-01-01
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多