PHP Fire and Forget POST Request

让人想犯罪 __ 提交于 2019-12-05 00:22:12

Yes, using sockets is the way to go if you don't care about the response from the URL you're calling. This is because socket connection can be terminated straight after sending the request without waiting and this is exactly what you're after - Fire and Forget.

Two notes though:

  1. It's no longer a cURL request, so it's worth renaming the function. :)
  2. It's definitely worth checking whether the socket could've been opened to prevent the script from complaining later when if fails:

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

It's worth linking to the original source of the fsocket() script you're now using:
http://w-shadow.com/blog/2007/10/16/how-to-run-a-php-script-in-the-background/

Here is a cleaned up version of diggersworld's code that also handles other HTTP methods then POST and throws meaningful exceptions if the function fails.

/**
 * 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);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!