fsockopen模拟http协议的post、get请求

作者: jaclon 分类: PHP 发布时间: 2010-12-10 13:07 ė 6没有评论

最近在做网站的时候要用到一个远程网站接口,主要是上传视频文件及相关信息并返回json数据。我把表单直接提交到远程接口,接口也正确返回信息,但是总是提示下载json文件。在网站找了一下没有发现在什么解决方案,后台就想到了fsockopen模拟http协议提交表单。
通过网摘及实际需求完善修改写了fsop.class文件,内容如下

class fsop {
	var $url; //要发送文件的URL
	var $formData; //发送的表单数据
	var $fileData; //文件数据
	var $boundary; //数据分隔标识
	var $response; //保存服务器返回的信息
	var $username; //需要身份验证时的用户名
	var $pwd; //需要身份验证时的密码
	var $port; //端口号
	var $method = 'GET';//提交方式
	var $crlf = "\r\n";//换行符


	var $debug = false; //是否调试


	/* 函数: fsop
	** 功能: Constructor
	** 参数: $url String 要发送文件的URL
	*/
	function fsop($url = "", $port = "80") {
		$this->url = $url;
		$this->port = $port;
		$this->boundary = $this->createBoundary ();
		$this->crlf = get_crlf();
	}

	/* 函数: sendRequest
	** 功能: 发送请求并保存结果
	*/
	function sendRequest($method = null) {
		@set_time_limit(600);
		$urlArray = parse_url ( $this->url );
		$fp = fsockopen ( $urlArray ['host'], $this->port );

		$requestData = $this->buildRequest($method); 

		//*
		fwrite ( $fp, $requestData );

		$content = "";
		while ( ! feof ( $fp ) ) {
			$content .= fread ( $fp, 4096 );
		}
		fclose ( $fp );
		//*/
		$this->response = $content;

		if ($this->debug) {
			echo "---------HTTP-REQUEST-------";
			echo "$requestData";
			echo "---------HTTP-RESPONSE------";
			echo "$content";
		}

		//*/
	}

	/* 函数: getResponse()
	** 功能: 返回服务器端的信息
	*/
	function getResponse() {
		return $this->response;
	}

	/* 函数: setForm( $formData )
	** 功能: 设置表单的字段值
	** 参数: $formData Array 字段名和值的数组
	*/
	function setForm($formData) {
		$this->formData = $this->buildFormData ( $formData );
	}

	/* 函数: setFile( $name, $filePath )
	** 功能: 设置要发送的文件
	** 参数: $name 文件名,即file域的name
	** 参数: $filePath 要发送的文件路径
	*/
	function setFile($name, $filePath, $content_type, $filename) {

		$this->fileData = $this->buildFileData($name,$filePath,$content_type
                                     ,$filename );
		$this->method = 'POST';
	}

	/* 函数: setAuthor( $user, $pwd )
	** 功能: 设置身份验证时需要的用户名和密码
	** 参数: $user 用户名
	** 参数: $pwd 密码
	*/
	function setAuthor($user, $pwd) {
		$this->username = $user;
		$this->pwd = $pwd;
	}

	/* 函数: buildRequest()
	** 功能: 建立请求
	*/
	function buildRequest($method) {
		$urlArray = parse_url ( $this->url );
		$method = empty($method) ? $this->method : strtoupper($method);
		$request = array ();

		if ($method == 'POST') {
			$request [] = "POST {$urlArray['path']} HTTP/1.0";
			$request [] = "Host: {$urlArray['host']}";
			$request [] = "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)";
			$request [] = "Accept: */*";
			$request [] = "Accept-Language: zh-cn";
			$request [] = "Connection: Keep-Alive";
			$request [] = "Cache-Control: no-cache";
	
			//需要身份验证
			if (! empty ($this->username ) && ! empty ($this->pwd)) {
				$request [] = 'Authorization: BASIC ' . base64_encode 
($this->username . ':' . $this->pwd );
			}
	
			$request [] = "Content-Type: multipart/form-data; boundary={$this->boundary}";
			$request [] = "Content-Length: " . $this->getDataLength () . $this->crlf;
	
			$requestString = join($this->crlf, $request).$this->crlf
.$this->formData. $this->crlf . $this->fileData;
		} else {
			$out = "GET {$urlArray['path']} HTTP/1.1".$this->crlf;
	   		$out .= "Host: {$urlArray['host']}".$this->crlf;
	   		$out .= "Connection: Close".$this->crlf.$this->crlf;
			$out .= "Accept: */*".$this->crlf;
			$out .= "Accept-Language: zh-cn".$this->crlf;
			$out .= "User-Agent: {$_SERVER['HTTP_USER_AGENT']}".$this->crlf;
			
			$requestString = $out;
		}

		if ($this->debug) {
			echo "----------- REQUEST_INFOMATION -----------";
			echo "" . $requestString . "";
		}
		return $requestString;
	}
	
	

	/* 函数: getDataLength()
	** 功能: 返回要发送数据的长度
	*/
	function getDataLength() {
		return strlen ( $this->formData ) + strlen ( $this->crlf )
 + strlen ( $this->fileData );
	}

	/* 函数: buildFormData()
	** 功能: 创建发送的数据格式
	*/
	function buildFormData($formData) {
		$postData = array ();
		foreach ( $formData as $k => $v ) {
			$row = array ();
			$row [] = "--{$this->boundary}";
			$row [] = "Content-Disposition: form-data; name=\"$k\"".$this->crlf;
			$row [] = "$v";

			$postData [] = join ( $this->crlf, $row );
		}
		$this->method = 'POST';

		return join ( $this->crlf, $postData );
	}
	
	/* 函数: buildFileData( $name, $filePath )
	** 功能: 创建发送的文件格式
	*/
	function buildFileData($name, $filePath, $content_type, $filename = '') {
		$fname = empty($filename) ? basename($filePath) : 
basename($filename);
		$fp = fopen($filePath, 'rb');
		$data = fread($fp, filesize($filePath));
		fclose($fp);
		
		$postData = array();
		$postData[] = "--{$this->boundary}";
		$postData[] = "Content-Disposition: form-data; name=\"$name\"; filename=\"$fname\"";
		$postData[] = "Content-Type: $content_type";
		$postData[] = "";
		$postData[] = $data;
		$postData[] = "--{$this->boundary}--";		

		return join($this->crlf, $postData);
	}

	/* 函数: createBoundary()
	** 功能: 创建数据分隔标识
	*/
	function createBoundary() {
		return "---------------------------" . substr ( md5 ( time () ), - 12 );
	}

}

使用方法

//表单数据
$data = array('title' => $title, 'author' => $author);

include_once S_ROOT.'./source/class_fsop.php';
$fsop = new fsop('http://dskb.hangzhou.com.cn/kbtv/api/article.json');
$fsop->setFile('upload', $tmp_name, $content_type, $FILE['name']);
$fsop->setForm($data);
$fsop->sendRequest();
$result = $fsop->getResponse();

解释:
upload 为file控件名称,
$tmp_name为要上传的文件地址,
$content_type为文MIME类型,如image/gif
$FILE[‘name’]为以什么文件名上传

如何判断请求是否成功
如果请求没有返回值则根据页面头部信息来判断请求是否成功。头部类似这样:

HTTP/1.1 200 OK
Date: Fri, 10 Dec 2010 08:08:33 GMT
Server: Apache/2.2.10 (Win32) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Set-Cookie: ZDEDebuggerPresent=php,phtml,php3; path=/
Set-Cookie: uchome_auth=deleted; expires=Thu, 10-Dec-2009 08:08:33 GMT;
Content-Length: 5
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

其中200 OK的200就是状态码表示服务器成功返回网页
如果是404- 请求的网页不存在
* 503- 服务器超时

本文出自 肥蕉博客@IT技术,热门话题,生活随笔,美图欣赏,转载时请注明出处及相应链接。

本文永久链接: http://www.bananawolf.com/html/2010/12/216.html

发表评论

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

*

Ɣ回顶部