1、使用curl实现
$start_time = time(); $url = 'https://www.google.com/'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 1); curl_exec($ch); curl_close($ch); $end_time = time(); echo 'done: ' . ($end_time - $start_time);
2、使用 Requests 实现
Requests 基于curl,所以和方式1是一样的
composer require rmccue/requests
<?php require './vendor/autoload.php'; $start_time = time(); $url = 'https://www.google.com/'; try { $res = Requests::get($url, [], ['timeout' => 1]); } catch (Exception $e) { echo 'Exception' . PHP_EOL; } $end_time = time(); echo 'done: ' . ($end_time - $start_time);
以上两种方式都可以实现异步调用,缺点是必须有1秒的延时…
3、使用 register_shutdown_function 实现
<?php class AsyncHook { private static $hook_list = array(); private static $hooked = false; /** * hook函数fastcgi_finish_request执行 * * @param callback $callback * @param array $params */ public static function hook($callback, $params = []) { self::$hook_list[] = array('callback' => $callback, 'params' => $params); if (self::$hooked == false) { self::$hooked = true; register_shutdown_function(array(__CLASS__, '__run')); } } /** * 由系统调用 * * @return void */ public static function __run() { if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } if (empty(self::$hook_list)) { return; } foreach (self::$hook_list as $hook) { $callback = $hook['callback']; $params = $hook['params']; call_user_func_array($callback, $params); } } }
测试
function timer() { sleep(5); echo 'timer done'; } $start_time = time(); AsyncHook::hook('timer'); $end_time = time(); echo 'done: ' . ($end_time - $start_time) . PHP_EOL; // done: 0 // timer done
该方法会继续执行代码,执行完成后并不会直接退出,而是会等待调用的方式都执行结束