PHP 模拟浏览器以 POST 的方式提交数据

以 POST 方式提交数据的原理就是,在 HTTP 请求头部以 POST 开头
如:POST /post/url HTTP/1.0
然后,在请求头中发送 POST 数据的数据的长度,再放松 \r\n\r\n
之后将 POST 数据发送,再发送 \r\n\r\n 结束。
下面在 php 中分别使用 curl, socket,file_get_contents 分别实现
以 POST 方式提交数据。

const SOCKET_EOL = "\r\n";
const USER_AGENT = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5';

/**
 * 通过curl 以 POST 方法提交数据
 * @param string $sUrl 请求的地址
 * @param  array$aData 需要提交的数据
 * @return mixed
 */
function post_via_curl($sUrl, $aData){
	$hCurl = curl_init();
	curl_setopt($hCurl, CURLOPT_URL, $sUrl);
	curl_setopt($hCurl, CURLOPT_POSTFIELDS, http_build_query($aData));
	curl_setopt($hCurl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($hCurl, CURLOPT_USERAGENT, USER_AGENT);
	$sResult = curl_exec($hCurl);
	curl_close($hCurl);
	return $sResult;
}

/**
 * 通过 socket 以 POST 方法提交数据
 * @param string $sUrl 请求的地址
 * @param  array$aData 需要提交的数据
 * @return bool|string
 */
function post_via_socket($sUrl, $aData){
	$aUrl = parse_url($sUrl);
	$sHost = $aUrl['host'];
	$sPort = $aUrl['port'];
	$hSocket = fsockopen($sHost, $sPort, $iErr, $sErr, 30);
	if($hSocket){
		$sPostData = http_build_query($aData);
		fwrite($hSocket, join(SOCKET_EOL, array(
			'POST ' . substr($sUrl, strpos($sUrl, '/')) . ' HTTP/1.0',
			'User-Agent: ' . USER_AGENT,
			'HOST: ' . $sHost,
			'Accept: */*',
			'Content-type: application/x-www-form-urlencoded',
			'Content-length: ' . strlen($sPostData),
			SOCKET_EOL,
			$sPostData,
			SOCKET_EOL
		)));
		$header = "";
		while($str = trim(fgets($hSocket, 4096))){
			$header .= $str;
		}
		$sResponse = "";
		while(!feof($hSocket)){
			$sResponse .= fgets($hSocket, 4096);
		}

		return $sResponse;
	}
	return false;
}

/**
 * 通过 file_get_contents 以 POST 方法提交数据
 * @param string $sUrl 请求的地址
 * @param  array$aData 需要提交的数据
 * @return string
 */
function post_via_file_get_contents($sUrl, $aData){
	$sPostData = http_build_query($aData);
	return file_get_contents($sUrl, FALSE, stream_context_create(array(
		'http' => array(
			'method' => 'POST',
			'header' => join(SOCKET_EOL, array(
				'User-Agent: ' . USER_AGENT,
				'Accept: */*',
				'Content-type: application/x-www-form-urlencoded',
				'Content-length: ' . strlen($sPostData),
			)),
			'content' => $sPostData
		)
	)));
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注