早就习惯了使用XmlHttpRequest来执行HTTP请求,虽然PHP自带的file类函数支持HTTP读取,但是不能自定义HTTP头是一个大问题。所以我就仿造MSXML2.XMLHTTP组件用socket封装了一个XmlHttpRequest类,虽然很简单,但是很方便~不敢独享,放出来给需要的朋友。
使用方法请见MSDN的参考,在此不在赘述。和MSXML2.XMLHTTP组件不同的地方就是获取相应只有responseContent属性可用。
代码如下:
[codesyntax lang=”php”]
/*
*XmlHttpRequest类
*By 枫行天下 starlight36@163.com
*Http://www.msphome.cn
*Ver 1.0 2009-11-15
*/
class XmlHttpRequest {
public $responseContent;
public $readyState = 0;
public $status;
public $statusText;
private $fp;
private $arrHeaders;
private $responseAll;
public function getAllResponseHeaders() {
if ($this->readyState != 4) return NULL;
$arrResponse = explode(“\r\n\r\n”, $this->responseAll);
return $arrResponse[0];
}
public function getResponseHeader($bstrHeader) {
if ($this->readyState != 4) return;
preg_match_all(“/{$bstrHeader}: (.+)/i”, $this->responseAll, $arrResponse);
return $arrResponse[1];
}
public function setRequestHeader($sName, $sValue) {
if ($this->readyState != 1) return;
$this->arrHeaders[] = $sName.”: “.$sValue;
}
public function open($sMethod, $sUrl) {
$arrUrl = parse_url($sUrl);
$arrUrl[‘port’] = isset($arrUrl[‘port’])? $arrUrl[‘port’] : 80;
$arrUrl[‘path’] = isset($arrUrl[‘path’])? $arrUrl[‘path’] : “/”;
$sScheme = (strtolower($arrUrl[‘scheme’]) == “https”) ? “ssl://” : NULL;
$sMethod = (strtolower($sMethod) == “post”) ? “POST” : “GET”;
$sUrl = isset($arrUrl[‘query’]) ? “?”.$arrUrl[‘query’] : NULL;
$sUrl = $arrUrl[‘path’].$sUrl;
$this->fp = fsockopen($sScheme.$arrUrl[‘host’], $arrUrl[‘port’], $errno, $errstr, 180);
if (!$this->fp) {
$this->readyState = 0;
$this->status = $errno;
$this->statusText = $errstr;
}else{
$this->readyState = 1;
$this->arrHeaders[] = $sMethod.” “.$sUrl.” HTTP/1.1″;
$this->setRequestHeader(“Accept”, “*/*”);
$this->setRequestHeader(“Host”, $arrUrl[‘host’]);
}
}
public function send($varBody = NULL) {
if ($this->readyState != 1) return;
if ($varBody != NULL) $this->setRequestHeader(“Content-Length”, strlen($varBody));
$this->setRequestHeader(“Connection”, “Close\r\n\r\n”);
$strHeader = implode(“\r\n”, $this->arrHeaders);
if ($varBody != NULL) $strHeader .= $varBody.”\r\n”;
$this->readyState = 2;
fwrite($this->fp, $strHeader);
$this->readyState = 3;
while (!feof($this->fp)) {
$this->responseAll .= fgets($this->fp, 512);
}
fclose($this->fp);
$arrResponse = explode(“\r\n”, $this->responseAll);
$this->status = substr($arrResponse[0], 9, 3);
$content = substr($this->responseAll, strpos($this->responseAll, “\r\n\r\n”) + 4);
if ($this->status >= 400) {
$this->statusText = $content;
}else{
$this->responseContent = $content;
}
$this->readyState = 4;
}
}
[/codesyntax]