如何在PHP中使用fsockopen运行异步任务

问题描述 投票:0回答:1

我正在尝试在PHP中使用fsockopen运行异步任务。实际上,我正在使用Codeigniter中的PHPMailer库发送电子邮件。我既没有收到任何错误,也没有收到包含以下代码的电子邮件...

public function sendingemail($mailer_admin_email,$mailer_sender_mail,$mailer_site_title,$mailer_subject,$mailer_message)
{
    $url = "someurl.com/handleasyncprocess/sendemail";
    $params = array(
        'mailer_admin_email' => $mailer_admin_email,
        'mailer_sender_mail' => $mailer_sender_mail,
        'mailer_site_title' => $mailer_site_title,
        'mailer_subject' => $mailer_subject, 
        'mailer_message' => $mailer_message,   
    );

    $post_string = http_build_query($params);
    $parts = parse_url($url);
    $errno = 0;
    $errstr = "";
    $ip = "**.**.**.**";

    $fp = fsockopen($ip, isset($parts['port']) ? $parts['port'] : 80, $errno, $errstr, 30);

    if(!$fp)
    {
        echo "Some thing Problem";    
    }
    $out = "POST ".$parts['path']." HTTP/1.1\r\n";
    $out.= "Host: ".$ip."\r\n";
    $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
    $out.= "Content-Length: ".strlen($post_string)."\r\n";
    $out.= "Connection: Close\r\n\r\n";
    if (isset($post_string)) $out.= $post_string;
    fwrite($fp, $out);
    fclose($fp);
}

请帮助!

php codeigniter phpmailer fsockopen
1个回答
0
投票

您可以使用此代码

$url = 'http://example.com';
$headers = array(
        "Content-Type"  => "application/x-www-form-urlencoded",
    //  "Connection"    => "Close",
    //  "no-respon"     => true
);

    $resp = http(NULL,$url,$headers,"POST","param=1&act=ok");
function timer_read($name,$timers) {
    if (isset($timers[$name]['start'])) {
    list($usec, $sec) = explode(' ', microtime());
    $stop = (float) $usec + (float) $sec;
    $diff = round(($stop - $timers[$name]['start']) * 1000, 2);

    if (isset($timers[$name]['time'])) {
      $diff += $timers[$name]['time'];
    }
    return $diff;
  }
}

function http($context, $url, $headers = array(), $method = 'GET', $data = NULL, $retry = 3, $timeout = 60, $connect_timeout = 30) {
  $result = new stdClass();

  $name   = "yhs_agent_http";
  $timers = array();
  $timers[$name] = array();

  list($usec, $sec) = explode(' ', microtime());
  $timers[$name]['start'] = (float) $usec + (float) $sec;
  $timers[$name]['count'] = isset($timers[$name]['count']) ? ++$timers[$name]['count'] : 1;


  // Parse the URL and make sure we can handle the schema.
  $uri = parse_url($url);

  switch ($uri['scheme']) {
    case 'http':
      $port = isset($uri['port']) ? $uri['port'] : 80;
      $host = $uri['host'] . ($port != 80 ? ':' . $port : '');
      $fp = fsockopen($uri['host'], $port, $errno, $errstr, $connect_timeout);
      break;
    case 'https':
      // Note: Only works for PHP 4.3 compiled with OpenSSL.
      if( is_null($context) ){
          $arrContextOptions=array(
            "ssl"=>array(
                "verify_peer"=>false,
                "verify_peer_name"=>false,
                )
            );  
            $context = stream_context_create($arrContextOptions);
      }
      $port = isset($uri['port']) ? $uri['port'] : 443;
      $host = $uri['host'] . ($port != 443 ? ':' . $port : '');
      if (!isset($context)) {
        $fp = fsockopen('ssl://' . $uri['host'], $port, $errno, $errstr, $connect_timeout);
      }
      else {
        $fp = stream_socket_client('ssl://' . $uri['host'] . ':' . $port, $errno, $errstr, $connect_timeout, STREAM_CLIENT_CONNECT, $context);
        if (!$fp && $errno == 0) {
          // An SSL error occurred.  I do not know of any way to get
          // an error code or message programmatically.  By not having
          // an @ before stream_socket_client(), the actual SSL error
          // will be logged via watchdog.
          $errno = 999;
          $errstr = 'SSL error creating socket';
        }
      }
      break;
    default:
      $result->error = 'invalid schema ' . $uri['scheme'];
      return $result;
  }

  // Make sure the socket opened properly.
  if (!$fp) {
    // When a network error occurs, we use a negative number so it does not
    // clash with the HTTP status codes.
    $result->code = -$errno;
    $result->error = trim($errstr);
    return $result;
  }

  // Construct the path to act on.
  $path = isset($uri['path']) ? $uri['path'] : '/';
  if (isset($uri['query'])) {
    $path .= '?' . $uri['query'];
  }

  // Create HTTP request.
  $defaults = array(
    // RFC 2616: "non-standard ports MUST, default ports MAY be included".
    // We don't add the port to prevent from breaking rewrite rules checking the
    // host that do not take into account the port number.
    'Host' => "Host: $host", 
    'User-Agent' => 'User-Agent:YHS-Agent',
  );

  // Only add Content-Length if we actually have any content or if it is a POST
  // or PUT request. Some non-standard servers get confused by Content-Length in
  // at least HEAD/GET requests, and Squid always requires Content-Length in
  // POST/PUT requests.
  if (!empty($data) || $method == 'POST' || $method == 'PUT') {
    $defaults['Content-Length'] = 'Content-Length: ' . @strlen($data);
  }

  // If the server url has a user then attempt to use basic authentication
  if (isset($uri['user'])) {
    $defaults['Authorization'] = 'Authorization: Basic ' . base64_encode($uri['user'] . (!empty($uri['pass']) ? ":" . $uri['pass'] : ''));
  }

  foreach ($headers as $header => $value) {
    $defaults[$header] = $header . ': ' . $value;
  }

  $request = $method . ' ' . $path . " HTTP/1.0\r\n";
  $request .= implode("\r\n", $defaults);
  $request .= "\r\n\r\n";
  if ($data) {
    $request .= $data . "\r\n";
  }
  $result->request = $request;

  if(isset($headers["no-respon"]) && $headers["no-respon"] == true ){
      fwrite($fp, $request);
      $respa = fread($fp, 1024);
      fclose($fp);
      return $respa;
  }

  // Calculate how much time is left of the original timeout value.
  $time_left = $timeout - timer_read($name,$timers) / 1000;
  if ($time_left > 0) {
    stream_set_timeout($fp, floor($time_left), floor(1000000 * fmod($time_left, 1)));
    fwrite($fp, $request);
  }



  // Fetch response.
  $response = '';
  while (!feof($fp)) {
    // Calculate how much time is left of the original timeout value.
    $time_left = $timeout - timer_read($name,$timers) / 1000;
    if ($time_left <= 0) {
      $result->code = -1;
      $result->error = 'request timed out';
      return $result;
    }
    stream_set_timeout($fp, floor($time_left), floor(1000000 * fmod($time_left, 1)));
    $chunk = fread($fp, 1024);
    $response .= $chunk;
  }
  fclose($fp);

  // Parse response.
  list($split, $result->data) = explode("\r\n\r\n", $response, 2);
  $split = preg_split("/\r\n|\n|\r/", $split);

  list($protocol, $code, $text) = explode(' ', trim(array_shift($split)), 3);
  $result->headers = array();

  // Parse headers.
  while ($line = trim(array_shift($split))) {
    list($header, $value) = explode(':', $line, 2);
    if (isset($result->headers[$header]) && $header == 'Set-Cookie') {
      // RFC 2109: the Set-Cookie response header comprises the token Set-
      // Cookie:, followed by a comma-separated list of one or more cookies.
      $result->headers[$header] .= ',' . trim($value);
    }
    else {
      $result->headers[$header] = trim($value);
    }
  }

  $responses = array(
    100 => 'Continue', 
    101 => 'Switching Protocols', 
    200 => 'OK', 
    201 => 'Created', 
    202 => 'Accepted', 
    203 => 'Non-Authoritative Information', 
    204 => 'No Content', 
    205 => 'Reset Content', 
    206 => 'Partial Content', 
    300 => 'Multiple Choices', 
    301 => 'Moved Permanently', 
    302 => 'Found', 
    303 => 'See Other', 
    304 => 'Not Modified', 
    305 => 'Use Proxy', 
    307 => 'Temporary Redirect', 
    400 => 'Bad Request', 
    401 => 'Unauthorized', 
    402 => 'Payment Required', 
    403 => 'Forbidden', 
    404 => 'Not Found', 
    405 => 'Method Not Allowed', 
    406 => 'Not Acceptable', 
    407 => 'Proxy Authentication Required', 
    408 => 'Request Time-out', 
    409 => 'Conflict', 
    410 => 'Gone', 
    411 => 'Length Required', 
    412 => 'Precondition Failed', 
    413 => 'Request Entity Too Large', 
    414 => 'Request-URI Too Large', 
    415 => 'Unsupported Media Type', 
    416 => 'Requested range not satisfiable', 
    417 => 'Expectation Failed', 
    500 => 'Internal Server Error', 
    501 => 'Not Implemented', 
    502 => 'Bad Gateway', 
    503 => 'Service Unavailable', 
    504 => 'Gateway Time-out', 
    505 => 'HTTP Version not supported',
  );
  // RFC 2616 states that all unknown HTTP codes must be treated the same as the
  // base code in their class.
  if (!isset($responses[$code])) {
    $code = floor($code / 100) * 100;
  }

  switch ($code) {
    case 200: // OK
    case 304: // Not modified
      break;
    case 301: // Moved permanently
    case 302: // Moved temporarily
    case 307: // Moved temporarily
      $location = $result->headers['Location'];

      $timeout -= timer_read($name,$timers) / 1000;
      if ($timeout <= 0) {
        $result->code = -1;
        $result->error = 'request timed out';
      }
      elseif ($retry) {
        $result = http($context, $result->headers['Location'], $headers, $method, $data, --$retry, $timeout, $connect_timeout);
        $result->redirect_code = $result->code;
      }
      $result->redirect_url = $location;

      break;
    default:
      $result->error = $text;
  }

  $result->code = $code;
  return $result;
}   
© www.soinside.com 2019 - 2024. All rights reserved.