搜索
首页php教程php手册php模拟post请求发送文件

php模拟post请求发送文件

由于项目需要,需要本地服务器接收数据后,再将数据转发到另外一台服务器上,故要用到模拟post请求发送数据,当然数据中也包含文件流。

curl是php比较常用的方式之一,一般代码如下:

 

$params1 = test;
$params2 = @.$absolute_path;//如果是文件 则参数为@+绝对路径
$post_data = array(  
	'params1' => $params1,  
	'params2' => $params2,
);
function postData($url, $data){      
	$ch = curl_init();      
	$timeout = 300;       
	curl_setopt($ch, CURLOPT_URL, $url);   //请求地址
	//curl_setopt($ch, CURLOPT_REFERER, $ip);//构造来路    
	curl_setopt($ch, CURLOPT_POST, true);  //post请求
	curl_setopt($ch, CURLOPT_BINARYTRANSFER,true);//二进制流    
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);      //数据
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //当CURLOPT_RETURNTRANSFER设置为1时 $head 有请求的返回值    
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);    //设置请求超时时间  
	$handles = curl_exec($ch);      
	curl_close($ch);		
	return $handles;
}
对方是java服务器,我只知道接口,并不知道对方如何处理文件接收的。上面这种方式在win7 wamp环境下是成功的,但是将代码放到centOS+Nginx服务器上却失败,返回的消息是文件接收失败。经过抓包分析,发现在win7 wamp下发的包和centos nginx下发的http包格式有区别。一般情况下curl默认把content_type设为了multipart/form-data,在我的机器上win7 wamp下是如此,但是centos nginx下却是application/x-www-form-urlencoded。当然这也可能是服务器配置问题,只是我并不知道问题在哪。然后我又查看了下PHP版本,同是PHP5.3.X,但是有细微差别。也不排除是PHP版本的问题。之后添加代码:

 

 

$header = array(
	'Content-Type: multipart/form-data',
);
curl_setopt( $ch, CURLOPT_HTTPHEADER, $header);
设置header,但是在centos下依旧无效。居然无法改变content-type,简直坑爹。

 

后来在技术总监的帮助下,看了PHP官方网站上的一个链接http://php.net/manual/en/class.curlfile.php,参照官网做法在win wamp和centos nginx下post请求都成功了。仔细阅读了代码,发现做法竟是完整的书写了http请求的body部分,而不用curl自己生成的部分,不得不佩服。下面放出代码:

 

function postData($url, $data = array(), $data1 = array()){      
	$header = array(
		'Content-Type: multipart/form-data',
	);
	$ch = curl_init(); 
	curl_setopt ($ch, CURLOPT_URL, $url);
	curl_setopt( $ch, CURLOPT_HTTPHEADER, $header);
	curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
	curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10);
	curl_setopt ($ch, CURLOPT_BINARYTRANSFER,true); 
	//curl_setopt ($ch, CURLOPT_POSTFIELDS, $data);
	curl_custom_postfields($ch, $data, $data1);
	$dxycontent = curl_exec($ch);
	curl_close($ch);
	return $dxycontent;
}

/**
* For safe multipart POST request for PHP5.3 ~ PHP 5.4.
* 
* @param resource $ch cURL resource
* @param array $assoc name => value
* @param array $files name => path
* @return bool
*/
function curl_custom_postfields($ch, array $assoc = array(), array $files = array()) {	
	// invalid characters for name and filename
	static $disallow = array(, , 
, 
);
	
	// build normal parameters
	foreach ($assoc as $k => $v) {
		$k = str_replace($disallow, _, $k);
		$body[] = implode(
, array(
			Content-Disposition: form-data; name={$k},
			,
			filter_var($v), 
		));
	}
	
	// build file parameters
	foreach ($files as $k => $v) {
		switch (true) {
			case false === $v = realpath(filter_var($v)):
			case !is_file($v):
			case !is_readable($v):
				continue; // or return false, throw new InvalidArgumentException
		}
		$data = file_get_contents($v);
		$v = call_user_func(end, explode(DIRECTORY_SEPARATOR, $v));
		$k = str_replace($disallow, _, $k);
		$v = str_replace($disallow, _, $v);
		$body[] = implode(
, array(
			Content-Disposition: form-data; name={$k}; filename={$v},
			Content-Type: application/octet-stream,
			,
			$data, 
		));
	}
	
	// generate safe boundary 
	do {
		$boundary = --------------------- . md5(mt_rand() . microtime());
	} while (preg_grep(/{$boundary}/, $body));
	
	// add boundary for each parameters
	array_walk($body, function (&$part) use ($boundary) {
		$part = --{$boundary}
{$part};
	});
	
	// add final boundary
	$body[] = --{$boundary}--;
	$body[] = ;
	
	// set options
	return @curl_setopt_array($ch, array(
		CURLOPT_POST       => true,
		CURLOPT_POSTFIELDS => implode(
, $body),
		CURLOPT_HTTPHEADER => array(
			Expect: 100-continue,
			Content-Type: multipart/form-data; boundary={$boundary}, // change Content-Type
		),
	));
}
参数传递无影响,若是文件则在绝对路径前+@。唯一的区别就是将文件数据和普通数据用不同的数组区分开来,在模拟http的body部分时对其进行不同的处理。最终成功上传文件。

 

 

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
wpsystem是什么文件夹wpsystem是什么文件夹Sep 01, 2022 am 11:22 AM

wpsystem文件夹是windows应用文件夹;创建WpSystem文件夹是为了存储某些特定“Microsoft Store”应用程序的数据,因此建议不要删该文件夹,因为删除之后就无法使用指定的应用。

winreagent是什么文件夹winreagent是什么文件夹Aug 26, 2022 am 11:23 AM

winreagent是在系统更新或升级的过程中创建的文件夹;该文件夹中通常包含临时文件,当更新或升级失败时,系统将通过还原先前创建的临时文件来回滚到执行更新或升级过程之前的版本。

baidunetdiskdownload是什么文件夹baidunetdiskdownload是什么文件夹Aug 30, 2022 am 10:45 AM

baidunetdiskdownload是百度网盘默认下载文件的文件夹;百度网盘是百度推出的一项云存储服务,只要下载东西到百度网盘里,都会默认保存到这个文件夹中,并且可跨终端随时随地查看和分享。

usmt.ppkg是什么文件usmt.ppkg是什么文件Sep 09, 2022 pm 02:14 PM

“usmt.ppkg”是windows自带的系统还原功能的系统备份文件;Windows系统还原是在不需要重新安装操作系统,也不会破坏数据文件的前提下使系统回到原有的工作状态,PBR恢复功能的备份文件就是“usmt.ppkg”。

mobileemumaster是什么文件mobileemumaster是什么文件Oct 26, 2022 am 11:28 AM

mobileEmuMaster是手机模拟大师的安装文件夹。手机模拟大师是PC电脑模拟运行安卓系统的免费模拟器程序,一款可以让用户在电脑上运行手机应用的软件,支持安装安卓系统中常见的apk执行文件,支持QQ、微信等生活常用应用,达到全面兼容的效果。

kml是什么文件的格式kml是什么文件的格式Sep 14, 2022 am 10:39 AM

kml是谷歌公司创建的一种地标性文件格式;该文件用于记录某一地点或连续地点的时间、经度、纬度、海拔等地理信息数据,可以被“Google Earth”和“Google Maps”识别并显示。

备份文件的扩展名通常是什么备份文件的扩展名通常是什么Sep 01, 2022 pm 03:55 PM

备份文件的扩展名通常是“.bak”;bak文件是一个备份文件,这类文件一般在'.bak前面加上应该有原来的扩展名,有的则是由原文件的后缀名和bak混合而成,在生成了某种类型的文件后,就会自动生成它的备份文件。

config是什么文件夹可以删除吗config是什么文件夹可以删除吗Sep 13, 2022 pm 03:48 PM

config是软件或者系统中的配置文件,不可以删除;该文件是在用户开机时对计算机进行初始化设置,也就是用户对系统的设置都由它来对计算机进行恢复,因此不能删除软件或者系统中的config配置文件,以免造成错误。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!