99久久国产露脸精品麻豆,欧美日韩精品小说,亚洲免费在线美女视频,国产三级中文字幕,91极品国产情侣高潮对白,国产亚洲一区二区三区不卡片,欧美jizz精品欧美性,久久国产精品久久国产片

PHP異步請求 fsockopen() 方法詳解

袁志蒙 1851次瀏覽

摘要:正常情況下,PHP執行的都是同步請求,代碼自上而下依次執行,但有些場景如發送郵件、執行耗時任務等操作時就不適用于同步請求,只能使用異步處理請求。場景要求:客戶端調用服...

正常情況下,PHP執行的都是同步請求,代碼自上而下依次執行,但有些場景如發送郵件、執行耗時任務等操作時就不適用于同步請求,只能使用異步處理請求。

場景要求:

客戶端調用服務器 a.php 接口,需要執行一個長達 10s-20s 不等的耗資源操作,假如客戶端響應請求時間為5秒(請求響應超時時間),5s 以上無回復即斷開連接。

解決設想:

客戶端調用 a.php 之后,a.php 執行異步多線程操作調用 b.php,a.php 調用成功后即刻反饋給客戶端回執,b.php 自動執行耗資源操作。

方案:

利用 fsockopen() 方法解決PHP異步請求


1.封裝異步請求函數 asyncRequest(),代碼如下:

/**
 * php異步請求
 * @param $url string 請求Url
 * @param $post array POST參數
 * @return string
 */
function asyncRequest($url, $post = array()){

	$matches = parse_url($url);
	!isset($matches['host']) && $matches['host'] = '';
	!isset($matches['path']) && $matches['path'] = '';
	!isset($matches['query']) && $matches['query'] = '';
	!isset($matches['port']) && $matches['port'] = 80;
	P($matches);
	$host = $matches['host'];
	$port = $matches['port'];
	$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';

	$post = $post && is_array($post) ? http_build_query($post) : '';
	$errno = 0;
	$errstr = '';
	$timeout = 30; //連接超時時間(S)

	if(function_exists('fsockopen')) {
	    $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
	} elseif (function_exists('pfsockopen')) {
	    $fp = @pfsockopen($host, $port, $errno, $errstr, $timeout);
	} elseif (function_exists('stream_socket_client')) {
	    $fp = @stream_socket_client('tcp://'.$host.':'.$port, $errno, $errstr, $timeout);
	} else {
	    $fp = false;
	}

	if (!$fp) {
		return '連接失敗';
	}
	if ($errno || !$fp) {
		return $errstr;
	}

	$out = "POST $path HTTP/1.1\r\n";
	$out .= "Accept: */*\r\n";
	//$out .= "Referer: $Referer\r\n";
	$out .= "Accept-Language: zh-cn\r\n";
	$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
	$out .= "User-Agent: ".$_SERVER['HTTP_USER_AGENT']."\r\n";
	$out .= "Host: $host\r\n";
	$out .= 'Content-Length: '.strlen($post)."\r\n";
	$out .= "Connection: Close\r\n";
	$out .= "Cache-Control: no-cache\r\n";
	$out .= $post;

	stream_set_blocking($fp, false); //非阻塞
	stream_set_timeout($fp, $timeout);//響應超時時間(S)
	$result = @fwrite($fp, $out);

	@fclose($fp);
	return $result;
}

2.正常接口 a.php,如下:

$url = 'http://localhost/b.php';
$param = array(
   'istest' => 1,
);

$asyncData = asyncRequest($url, $param);
echo 'a.php success';

3.耗時接口 b.php,如下:

set_time_limit(0);
ignore_user_abort(true);//設置與客戶機斷開是否會終止執行
fastcgi_finish_request();//提高請求的處理速度

sleep(15);
echo "耗時15秒";


隨機內容

表情

共1條評論
  • 網友評論:

    實用

    2023-10-07 20:22:43 回復

    點擊加載