PHP Fire and Forget Запрос POST

Я пытаюсь создать огонь и забыть метод в PHP, чтобы я мог POST данные POST на веб-сервер и не ждать ответа. Я читал, что это может быть достигнуто с помощью CURL как в следующем коде:

 $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); curl_exec($ch); curl_close($ch); 

Однако я не думаю, что это работает, как я ожидаю. Например, если в URL-адресе, который я отправляю запрос, есть ошибка, это заставляет мой скрипт также вызывать ошибку. Если бы это был огонь и забыть, я бы ожидал, что этого не произойдет.

Может ли кто-нибудь сказать мне, что я делаю что-то неправильно или предлагаю альтернативное предложение. Я использую Windows локально и Linux для разработчиков, промежуточных и производственных сред.

ОБНОВИТЬ

Я нашел альтернативное решение здесь: http://blog.markturansky.com/archives/205

Я очистил его в коде ниже:

 function curl_post_async($url, $params = array()) { // create POST string $post_params = array(); foreach ($params as $key => &$val) { $post_params[] = $key . '=' . urlencode($val); } $post_string = implode('&', $post_params); // get URL segments $parts = parse_url($url); // workout port and open socket $port = isset($parts['port']) ? $parts['port'] : 80; $fp = fsockopen($parts['host'], $port, $errno, $errstr, 30); // create output string $output = "POST " . $parts['path'] . " HTTP/1.1\r\n"; $output .= "Host: " . $parts['host'] . "\r\n"; $output .= "Content-Type: application/x-www-form-urlencoded\r\n"; $output .= "Content-Length: " . strlen($post_string) . "\r\n"; $output .= "Connection: Close\r\n\r\n"; $output .= isset($post_string) ? $post_string : ''; // send output to $url handle fwrite($fp, $output); fclose($fp); } 

Кажется, это работает лучше для меня.

Это приемлемое решение?

Solutions Collecting From Web of "PHP Fire and Forget Запрос POST"

Да, использование сокетов – это способ пойти, если вам не нужен ответ от URL-адреса, который вы вызываете. Это связано с тем, что соединение сокетов может быть прекращено сразу после отправки запроса без ожидания, и это именно то, что вам нужно – Fire and Forget.

Две заметки:

  1. Это больше не запрос cURL, поэтому стоит переименовать функцию. 🙂
  2. Это определенно стоит проверить, мог ли сокет быть открыт, чтобы предотвратить скрипт позже, если в случае сбоя:

     $fp = fsockopen($parts['host'], $port, $errno, $errstr, 30); if ( ! $fp) { return FALSE; } 

Стоит связать исходный исходный код скрипта fsocket (), который вы используете сейчас:
http://w-shadow.com/blog/2007/10/16/how-to-run-a-php-script-in-the-background/

Я бы предложил использовать Guzzle для этого: http://docs.guzzlephp.org/en/latest/quickstart.html#concurrent-requests

 use GuzzleHttp\Client; use GuzzleHttp\Promise; $client = new Client(['base_uri' => 'http://httpbin.org/']); // Initiate each request but do not block $promises = [ 'image' => $client->getAsync('/image'), 'png' => $client->getAsync('/image/png'), 'jpeg' => $client->getAsync('/image/jpeg'), 'webp' => $client->getAsync('/image/webp') ]; // Wait on all of the requests to complete. Throws a ConnectException // if any of the requests fail $results = Promise\unwrap($promises); // Wait for the requests to complete, even if some of them fail $results = Promise\settle($promises)->wait();