PHP中是否有一种方法可以使HTTP调用不等待响应?我不关心响应,我只想做一些类似file_get_contents()的事情,但不等待请求完成后再执行其余的代码。这对于在我的应用程序中触发某种“事件”或触发长进程非常有用。

什么好主意吗?


当前回答

你可以在PHP中使用非阻塞套接字和pecl扩展之一:

http://php.net/event http://php.net/libevent http://php.net/ev https://github.com/m4rw3r/php-libev

您可以使用库,它为您的代码和pecl扩展之间提供了一个抽象层:https://github.com/reactphp/event-loop

您还可以使用基于前面库的异步http-client: https://github.com/reactphp/http-client

查看ReactPHP的其他库:http://reactphp.org

使用异步模型时要小心。 我推荐在youtube上看这个视频:http://www.youtube.com/watch?v=MWNcItWuKpI

其他回答

ReactPHP异步http客户端 https://github.com/shuchkin/react-http-client

通过Composer安装

$ composer require shuchkin/react-http-client

异步HTTP GET

// get.php
$loop = \React\EventLoop\Factory::create();

$http = new \Shuchkin\ReactHTTP\Client( $loop );

$http->get( 'https://tools.ietf.org/rfc/rfc2068.txt' )->then(
    function( $content ) {
        echo $content;
    },
    function ( \Exception $ex ) {
        echo 'HTTP error '.$ex->getCode().' '.$ex->getMessage();
    }
);

$loop->run();

在cli模式下运行php

$ php get.php
/**
 * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere. 
 *
 * @param string $filename              file to execute, relative to calling script
 * @param string $options               (optional) arguments to pass to file via the command line
 */ 
function asyncInclude($filename, $options = '') {
    exec("/path/to/php -f {$filename} {$options} >> /dev/null &");
}

下面是一个工作示例,只需运行它,然后打开storage.txt,检查神奇的结果

<?php
    function curlGet($target){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $target);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec ($ch);
        curl_close ($ch);
        return $result;
    }

    // Its the next 3 lines that do the magic
    ignore_user_abort(true);
    header("Connection: close"); header("Content-Length: 0");
    echo str_repeat("s", 100000); flush();

    $i = $_GET['i'];
    if(!is_numeric($i)) $i = 1;
    if($i > 4) exit;
    if($i == 1) file_put_contents('storage.txt', '');

    file_put_contents('storage.txt', file_get_contents('storage.txt') . time() . "\n");

    sleep(5);
    curlGet($_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . '?i=' . ($i + 1));
    curlGet($_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . '?i=' . ($i + 1));
class async_file_get_contents extends Thread{
    public $ret;
    public $url;
    public $finished;
        public function __construct($url) {
        $this->finished=false;
        $this->url=$url;
    }
        public function run() {
        $this->ret=file_get_contents($this->url);
        $this->finished=true;
    }
}
$afgc=new async_file_get_contents("http://example.org/file.ext");

你可以在PHP中使用非阻塞套接字和pecl扩展之一:

http://php.net/event http://php.net/libevent http://php.net/ev https://github.com/m4rw3r/php-libev

您可以使用库,它为您的代码和pecl扩展之间提供了一个抽象层:https://github.com/reactphp/event-loop

您还可以使用基于前面库的异步http-client: https://github.com/reactphp/http-client

查看ReactPHP的其他库:http://reactphp.org

使用异步模型时要小心。 我推荐在youtube上看这个视频:http://www.youtube.com/watch?v=MWNcItWuKpI