扫码关注官方订阅号
最近开发中遇到这么一个问题,程序第4行会请求一个url,但是这个url的响应时间很长,而且我的程序中用不到他的返回值,所以我在想能不能在第4行发送请求之后不用等待他返回值,直接执行第5行代码,可以吗?如果可以的话,怎么做到?
小伙看你根骨奇佳,潜力无限,来学PHP伐。
http://www.laruence.com/2008/04/14/318.html
sleep(10)这个长达10秒的操作由正在提供Web服务的PHP进程来处理显然是不合适的,因为这肯定会造成一个PHP工作进程被阻塞.这时可以考虑用popen或proc_open异步调用一个CLI程序进行一些耗时的操作.
/www/index.php <?php $sec = 10; //pclose(popen('/www/cli.php '.$sec.' &', 'r')); pclose(popen("/www/cli.php -s $sec &", 'r')); /www/cli.php #!/png/php/5.4.39NTS/bin/php <?php $argv = getopt('s:'); sleep($argv['s']); file_put_contents('/www/cli.txt', $argv['s']); //print_r($argv); //cli.php处理完耗时的任务后往数据库存结果,浏览器端用AJAX轮询异步得到数据.
之前我也有类似的场景,一开始用curl实现,设置超时时间让请求发起后就马上超时返回,发现还是有几百毫秒的消耗,改用fsockopen,附上之前用fsockopen实现的功能类:
<?php /** * http异步客户端 * Created by JetBrains PhpStorm. * User: huangnaiang * Date: 14-6-30 * Time: 下午7:47 * To change this template use File | Settings | File Templates. */ class HttpAsyncRequest { //get请求方式 const METHOD_GET = 'GET'; //post请求方式 const METHOD_POST = 'POST'; /** * 发起http异步请求 * @param string $url http地址 * @param string $method 请求方式 * @param array $params 参数 * @param string $ip 支持host配置 * @param int $connectTimeout 连接超时,单位为秒 * @throws Exception */ public static function exec($url, $method = self::METHOD_GET, $params = array(), $ip = null, $connectTimeout = 1) { $urlInfo = parse_url($url); $host = $urlInfo['host']; $port = isset($urlInfo['port']) ? $urlInfo['port'] : 80; $path = isset($urlInfo['path']) ? $urlInfo['path'] : '/'; !$ip && $ip = $host; $method = strtoupper(trim($method)) !== self::METHOD_POST ? self::METHOD_GET : self::METHOD_POST; $params = http_build_query($params); if($method === self::METHOD_GET && strlen($params) > 0){ $path .= '?' . $params; } $fp = fsockopen($ip, $port, $errorCode, $errorInfo, $connectTimeout); if($fp === false){ throw new Exception('Connect failed , error code: ' . $errorCode . ', error info: ' . $errorInfo); } else{ $http = "$method $path HTTP/1.1\r\n"; $http .= "Host: $host\r\n"; $http .= "Content-type: application/x-www-form-urlencoded\r\n"; $method === self::METHOD_POST && $http .= "Content-Length: " . strlen($params) . "\r\n"; $http .= "\r\n"; $method === self::METHOD_POST && $http .= $params . "\r\n\r\n"; if(fwrite($fp, $http) === false || fclose($fp) === false){ throw new Exception('Request failed.'); } } } }
如果你用不到这个返回,你可以直接把这个地址存到数据库,由别的程序在服务器上执行
要是用php-fpm可以看看这个函数fastcgi_finish_request你把运行慢的代码写在这个函数之后就可以了http://php.net/manual/zh/function.fastcgi-finish-request.php
fastcgi_finish_request
可以使用 php 异步扩展 swoole.
可以用多线程,pthread扩展,http://php.net/manual/en/book.pthreads.php
把请求操作放在队列中,异步执行
<?php $context = stream_context_create(array( 'http' => array( 'timeout' => 5 ) )); $contents = file_get_contents('http://www.google.com', 0, $context); echo '5秒后到这' ?>
用队列请求用队列请求用队列请求
这肯定是不可以的 !
要么你使用队列执行 .要么 你用 swoole 或者 Node.js
PHP 在设计上就决定了 , 它只能从头到尾执行 。
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
http://www.laruence.com/2008/04/14/318.html
sleep(10)这个长达10秒的操作由正在提供Web服务的PHP进程来处理显然是不合适的,因为这肯定会造成一个PHP工作进程被阻塞.这时可以考虑用popen或proc_open异步调用一个CLI程序进行一些耗时的操作.
之前我也有类似的场景,一开始用curl实现,设置超时时间让请求发起后就马上超时返回,发现还是有几百毫秒的消耗,改用fsockopen,附上之前用fsockopen实现的功能类:
如果你用不到这个返回,你可以直接把这个地址存到数据库,由别的程序在服务器上执行
要是用php-fpm可以看看这个函数
fastcgi_finish_request你把运行慢的代码写在这个函数之后就可以了
http://php.net/manual/zh/function.fastcgi-finish-request.php
可以使用 php 异步扩展 swoole.
可以用多线程,pthread扩展,http://php.net/manual/en/book.pthreads.php
把请求操作放在队列中,异步执行
用队列请求
用队列请求
用队列请求
这肯定是不可以的 !
要么你使用队列执行 .
要么 你用 swoole 或者 Node.js
PHP 在设计上就决定了 , 它只能从头到尾执行 。