19

POSTPHPでファイアアンドフォーゲットメソッドを作成して、Webサーバーにデータを送信し、応答を待たないようにしようとしています。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);
}

これは私にとってはうまくいくようです。

それは有効な解決策ですか?

4

2 に答える 2

10

はい、呼び出しているURLからの応答を気にしない場合は、ソケットを使用するのが最善の方法です。これは、要求を送信した直後にソケット接続を待機せずに終了できるためです。これはまさにあなたが求めているものです-ファイアアンドフォーゲット。

ただし、2つの注意事項:

  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 -背景/

于 2013-02-20T14:42:40.827 に答える
5

これは、他のHTTPメソッドを処理してからPOSTを実行し、関数が失敗した場合に意味のある例外をスローするdiggersworldのコードのクリーンアップバージョンです。

/**
 * Send a HTTP request, but do not wait for the response
 *
 * @param string $method The HTTP method
 * @param string $url The url (including query string)
 * @param array $params Added to the URL or request body depending on method
 */
public function sendRequest(string $method, string $url, array $params = []): void
{
    $parts = parse_url($url);
    if ($parts === false)
        throw new Exception('Unable to parse URL');
    $host = $parts['host'] ?? null;
    $port = $parts['port'] ?? 80;
    $path = $parts['path'] ?? '/';
    $query = $parts['query'] ?? '';
    parse_str($query, $queryParts);

    if ($host === null)
        throw new Exception('Unknown host');
    $connection = fsockopen($host, $port, $errno, $errstr, 30);
    if ($connection === false)
        throw new Exception('Unable to connect to ' . $host);
    $method = strtoupper($method);

    if (!in_array($method, ['POST', 'PUT', 'PATCH'], true)) {
        $queryParts = $params + $queryParts;
        $params = [];
    }

    // Build request
    $request  = $method . ' ' . $path;
    if ($queryParts) {
        $request .= '?' . http_build_query($queryParts);
    }
    $request .= ' HTTP/1.1' . "\r\n";
    $request .= 'Host: ' . $host . "\r\n";

    $body = http_build_query($params);
    if ($body) {
        $request .= 'Content-Type: application/x-www-form-urlencoded' . "\r\n";
        $request .= 'Content-Length: ' . strlen($body) . "\r\n";
    }
    $request .= 'Connection: Close' . "\r\n\r\n";
    $request .= $body;

    // Send request to server
    fwrite($connection, $request);
    fclose($connection);
}
于 2019-10-22T12:50:48.270 に答える