哪位大侠有使用CURL设置HTTPHEADER来上传文件的经验?
求指点
PS:不是 '@'.文件名,而是Content-Type: application/octet-stream
回复讨论(解决方案)
curl不支持这种方式,你需要自己构造数据包。我研究过
curl不支持这种方式,你需要自己构造数据包。我研究过
是否有示例?
http://cn.php.net/fsockopen
CTRL + F搜索boundary,例子好好看看,构建一个文件上传的http请求头即可,按理说CURL构建同样的请求头应该也没问题。
总结一下项目中用到curl的几种方式
1. php curl的默认调用方法,get方式访问url
Java代码
....
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //设置http头
curl_setopt($ch, CURLOPT_ENCODING, "gzip" ); //设置为客户端支持gzip压缩
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30 ); //设置连接等待时间
curl_setopt($ch, CURLOPT_URL, $url );
curl_exec( $ch );
if ($error = curl_error($ch) ) {
//出错处理
return -1;
}
fclose($fp);
$curl_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); //获取http返回值
if( $curl_code == 200 ) {
//正常访问url
}
//异常
....
....
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //设置http头
curl_setopt($ch, CURLOPT_ENCODING, "gzip" ); //设置为客户端支持gzip压缩
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30 ); //设置连接等待时间
curl_setopt($ch, CURLOPT_URL, $url );
curl_exec( $ch );
if ($error = curl_error($ch) ) {
//出错处理
return -1;
}
fclose($fp);
$curl_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); //获取http返回值
if( $curl_code == 200 ) {
//正常访问url
}
//异常
....
2. 设置http header支持curl访问lighttpd服务器
Java代码
$header[]= 'Expect:';
$header[]= 'Expect:';
3. 设置curl,只获取http header,不获取body:
Java代码
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
或者只获取body:
Java代码
curl_setopt($ch, CURLOPT_HEADER, 0); // make sure we get the body
curl_setopt($ch, CURLOPT_NOBODY, 0);
curl_setopt($ch, CURLOPT_HEADER, 0); // make sure we get the body
curl_setopt($ch, CURLOPT_NOBODY, 0);
4. 访问虚拟主机,需设置Host
$header[]= 'Host: '.$host;
5. 使用post, put, delete等REStful方式访问url
post:
curl_setopt($ch, CURLOPT_POST, 1 );
put, delete:
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); //或者PUT,需要服务器支持这些方法。
6. 保存下载内容为文件
curl_setopt($ch, CURLOPT_FILE, $fp);
总结一下项目中用到curl的几种方式
1. php curl的默认调用方法,get方式访问url
Java代码
....
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //设置http头
curl_setopt($ch, CURLOPT_ENCO……
貌似没看到使用了CURLOPT_HTTPHEADER
http://cn.php.net/fsockopen
CTRL + F搜索boundary,例子好好看看,构建一个文件上传的http请求头即可,按理说CURL构建同样的请求头应该也没问题。
谢谢,CURL不支持这种上传方法吗?
可能是比较复杂吧,所以 curl 提供了 '@'.文件名 的方式。把构造头和数据的工作留给了自己
但 curl 依然提供了 CURLOPT_UPLOAD 来表示上传文件,但实际上使用了 PUT 请求
只适合向 ftp 上传文件
在 php 中,要从 php://input 读取
使用 #5 给出的代码,会产生 无法识别的请求 这样的错误,注释掉文件上传的那段,依然报这个错。不知是什么原因
但对比 curl PUT 方式的数据报,似乎也没有什么差异
知道了,这样写就可以!
$contents =<<< 'TEXT'数据报中应该是Content-Disposition: form-data; name="userfile"; filename="file_name"Content-Type: 文档类型文件内容这样的格式,我只实现了文件名部分,文档类型不知道如何实现。这样上传后就取不到 type 的值curl_upload_server.php<xmp><?phpprint_r($_FILES);echo "文件内容:\n";$p = current($_FILES);readfile($p['tmp_name']);TEXT;$fields['f"; filename="x.x'] = $contents; //这个关联键的写法很怪异吧?$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://localhost/curl_upload_server.php"); curl_setopt($ch, CURLOPT_POST, 1 );curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$s = curl_exec ($ch); curl_close ($ch); echo $s;
原来这样就有 type了
$varname = 'my';$name = '3.txt';$type = 'text/plain';$key = <<< TEXT$varname"; filename="$nameContent-Type: $typeTEXT;$fields[$key] = $contents;
注意:我是在 win 下的,linux 下要将 \n 换成 \r\n
没办法,早年的 sun 是拼不过 ms 的,现在也不行吧?
一直以为上传的文件类型是 php 识别的,却原来是浏览器提供的
原来这样就有 type了PHP code
$varname = 'my';
$name = '3.txt';
$type = 'text/plain';
$key = $varname"; filename="$name
Content-Type: $type
TEXT;
$fields[$key] = $contents;
注意:我是在 win 下的,linux 下……
很感谢,有没有比较完整的CURL 通过拼接HTTPHEADER信息上传的POST示例呢?
#10 就是
curl_upload_server.php 就是测试用服务器端
print_r($_FILES);
echo "文件内容:\n";
$p = current($_FILES);
readfile($p['tmp_name']);
完整的代码
$contents =<<< 'TEXT'数据报中应该是Content-Disposition: form-data; name="userfile"; filename="file_name"Content-Type: 文档类型文件内容这样的格式以下是服务器端代码curl_upload_server.php<xmp><?phpprint_r($_FILES); //检查上传信息echo "文件内容:\n";$p = current($_FILES);readfile($p['tmp_name']); //输出上传的文件TEXT;$varname = 'my';$name = '3.txt';$type = 'text/plain';$key = "$varname\"; filename=\"$name\r\nContent-Type: $type\r\n";$fields[$key] = $contents;$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://localhost/curl_upload_server.php"); curl_setopt($ch, CURLOPT_POST, 1 );curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$s = curl_exec ($ch); curl_close ($ch); echo $s;
http文件上传协议,主要是那个boundary,这个东西就是标识一个文件的内容和类型以及各种上传参数的token,其它和普通的POST提交也没啥区别。
fsockopen来写http请求就比较直白,用curl的话模拟对应的请求头和body就好了。
<?php//what file you want to upload$uploadFile = file_get_contents("/var/www/index.html");//content boundary $boundary = md5(time());$postStr = "";$postStr .="--".$boundary."\r\n";$postStr .="Content-Disposition: form-data; name=\"uptxt\"; filename=\"index.html\"\r\n";$postStr .="Content-Type: text/html\r\n\r\n";$postStr .=$uploadFile."\r\n";$postStr .="--".$boundary."\r\n"; /** use fsockopen to set upload http header and body **/$fp = fsockopen("localhost","80",$errer,$errno,1);fwrite($fp,"POST /upload.php HTTP/1.0\r\n");fwrite($fp,"Content-Type: multipart/form-data; boundary=".$boundary."\r\n");fwrite($fp,"Content-length:".strlen($postStr)."\r\n\r\n");fwrite($fp,$postStr);while (!feof($fp)){ echo fgets($fp, 128);}fclose($fp);/** use curl instead **/$cl = curl_init('http://localhost/upload.php');$boundary = md5(time());curl_setopt($cl,CURLOPT_POST,true);curl_setopt($cl,CURLOPT_HTTPHEADER,array( "Content-Type: multipart/form-data; boundary=".$boundary));curl_setopt($cl,CURLOPT_POSTFIELDS,$postStr);curl_setopt($cl,CURLOPT_RETURNTRANSFER,true);$content = curl_exec($cl);curl_close($cl);echo $content;?>
upload.php
<?php print_r($_FILES);?>
结果
HTTP/1.1 200 OKServer: nginx/0.8.54Date: Tue, 10 Apr 2012 05:22:01 GMTContent-Type: text/htmlConnection: closeX-Powered-By: PHP/5.3.10Array( [uptxt] => Array ( [name] => index.html [type] => text/html [tmp_name] => /tmp/phpKHfxkY [error] => 0 [size] => 344 ))Array( [uptxt] => Array ( [name] => index.html [type] => text/html [tmp_name] => /tmp/phpB0se13 [error] => 0 [size] => 344 ))
完整的代码PHP code
$contents = 数据报中应该是
Content-Disposition: form-data; name="userfile"; filename="file_name"
Content-Type: 文档类型
文件内容
这样的格式
以下是服务器端代码
curl_upload_server.php
print_r(……
没有client?
完整的代码PHP code
$contents = 数据报中应该是
Content-Disposition: form-data; name="userfile"; filename="file_name"
Content-Type: 文档类型
文件内容
这样的格式
以下是服务器端代码
curl_upload_server.php
print_r(……
最好能分开发一下,谢谢
http文件上传协议,主要是那个boundary,这个东西就是标识一个文件的内容和类型以及各种上传参数的token,其它和普通的POST提交也没啥区别。
fsockopen来写http请求就比较直白,用curl的话模拟对应的请求头和body就好了。
PHP code
//what file you want to upload
$uploadFile = file_get_……
非常感谢,CURL部分的代码我这边测试成功了,我再加一百分
#14 服务器端
#15 客户端
#14 中的 $contents 是待上传的文件内容
上次好像看到你问的是一个文件切分多份,然后上传,如果是这样的话,你要要做的只是用boundary标识多个上传内容区块。比如
$boundary = md5(time());$postStr = "";$postStr .="--".$boundary."\r\n";$postStr .="Content-Disposition: form-data; name=\"uptxt[]\"; filename=\"index_1.html\"\r\n";$postStr .="Content-Type: text/html\r\n\r\n";$postStr .=$uploadFile."\r\n"; #这里是部分文件内容$postStr .="--".$boundary."\r\n";$postStr .="--".$boundary."\r\n";$postStr .="Content-Disposition: form-data; name=\"uptxt[]\"; filename=\"index_2.html\"\r\n"; $postStr .="Content-Type: text/html\r\n\r\n";$postStr .=$uploadFile."\r\n";#这里是部分文件内容$postStr .="--".$boundary."\r\n";
收藏了!
to #21
你这样做是不行的,应该使用 curl_multi 并发
不然把一个文件拆成几个, 一次性传出,再在服务器端组装。有什么意义?
上次好像看到你问的是一个文件切分多份,然后上传,如果是这样的话,你要要做的只是用boundary标识多个上传内容区块。比如
PHP code
$boundary = md5(time());
$postStr = "";
$postStr .="--".$boundary."\r\n";
$postStr .="Content-Disposition: form-data; name=……
我用了个循环来做
引用 21 楼 的回复:
上次好像看到你问的是一个文件切分多份,然后上传,如果是这样的话,你要要做的只是用boundary标识多个上传内容区块。比如
PHP code
$boundary = md5(time());
$postStr = "";
$postStr .="--".$boundary."\r\n";
$postStr .="Content-Dispositi……
感谢,curl_multi很有用
to #21
你这样做是不行的,应该使用 curl_multi 并发
不然把一个文件拆成几个,一次性传出,再在服务器端组装。有什么意义?
说的也是哈,不过curl_multi的并发,对于请求不同的url后获取数据比较有意义,就是说是并行请求不同的url获取http返回。如果往同一url请求,要么就一次请求,要么就分发多次请求,多次请求有个性能消耗在于每次都要scoket连接/销毁,但是能控制请求字节数。
引用 23 楼 的回复:
to #21
你这样做是不行的,应该使用 curl_multi 并发
不然把一个文件拆成几个,一次性传出,再在服务器端组装。有什么意义?
说的也是哈,不过curl_multi的并发,对于请求不同的url后获取数据比较有意义,就是说是并行请求不同的url获取http返回。如果往同一url请求,要么就一次请求,要么就分发多次请求,多次请求有个性能消耗在于每……
忘了如果服务器支持keep-alive的话,无需进行多次socket create,呵呵
一路上传不能充分利用网络资源,多路并发可使上传速度加快
引用 26 楼 的回复:
引用 23 楼 的回复:
to #21
你这样做是不行的,应该使用 curl_multi 并发
不然把一个文件拆成几个,一次性传出,再在服务器端组装。有什么意义?
说的也是哈,不过curl_multi的并发,对于请求不同的url后获取数据比较有意义,就是说是并行请求不同的url获取http返回。如果往同一url请求,要么就一次请求,要么就分发多……
嗯,基本上都支持keep-alive了
一路上传不能充分利用网络资源,多路并发可使上传速度加快
嗯,网络利用率更高
CSDN的编辑器还是没改进,同时回复多个还需要手动复制代码。。。
嗯,服务器可开多线程/进程处理你的并发上传请求,这是快的缘故。
只要资源够,多开几路并无大碍,至多大部被阻塞了,就相当于单路
设计成多路传输的好处还有,当某段数据传输失败时,可以重传这段。
这是单路传输设计做不到的
http://cn.php.net/fsockopen
CTRL + F搜索boundary,例子好好看看,构建一个文件上传的http请求头即可,按理说CURL构建同样的请求头应该也没问题。
照着PHP手册里去做反而没成功
引用 5 楼 的回复:
http://cn.php.net/fsockopen
CTRL + F搜索boundary,例子好好看看,构建一个文件上传的http请求头即可,按理说CURL构建同样的请求头应该也没问题。
照着PHP手册里去做反而没成功
是吗?你不如用wireshark,smartsniff等工具查看http请求格式(firebug或者chrome自带的F12应该也可以),执行一次上传文件动作,然后观察文件上传时的http请求格式。
贴个post的socket代码:
我测试过的备份!
http://webinno.cn/blog/article/view/40
CURLOPT_HEADERFUNCTION这个参数可以设置HTTP协议回调,你可以参考下
curl只要你设置些参数,然后他自己会生成协议头提交服务器
谢谢大家!
我只用过Content-Type提供下载.
不错!!!!!!
我也要一份

aphpdepentioncontiveContainerIsatoolThatManagesClassDeptions,增强codemodocultion,可验证性和Maintainability.itactsasaceCentralHubForeatingingIndections,因此reducingTightCightTightCoupOulplingIndeSingantInting。

选择DependencyInjection(DI)用于大型应用,ServiceLocator适合小型项目或原型。1)DI通过构造函数注入依赖,提高代码的测试性和模块化。2)ServiceLocator通过中心注册获取服务,方便但可能导致代码耦合度增加。

phpapplicationscanbeoptimizedForsPeedAndeffificeby:1)启用cacheInphp.ini,2)使用preparedStatatementSwithPdoforDatabasequesies,3)3)替换loopswitharray_filtaray_filteraray_maparray_mapfordataprocrocessing,4)conformentnginxasaseproxy,5)

phpemailvalidation invoLvesthreesteps:1)格式化进行regulareXpressecthemailFormat; 2)dnsvalidationtoshethedomainhasavalidmxrecord; 3)

tomakephpapplicationsfaster,关注台词:1)useopcodeCachingLikeLikeLikeLikeLikePachetoStorePreciledScompiledScriptbyTecode.2)MinimimiedAtabaseSqueriSegrieSqueriSegeriSybysequeryCachingandeffeftExting.3)Leveragephp7 leveragephp7 leveragephp7 leveragephpphp7功能forbettercodeefficy.4)

到ImprovephPapplicationspeed,关注台词:1)启用opcodeCachingwithapCutoredUcescriptexecutiontime.2)实现databasequerycachingusingpdotominiminimizedatabasehits.3)usehttp/2tomultiplexrequlexrequestsandredececonnection.4 limitsclection.4.4

依赖注入(DI)通过显式传递依赖关系,显着提升了PHP代码的可测试性。 1)DI解耦类与具体实现,使测试和维护更灵活。 2)三种类型中,构造函数注入明确表达依赖,保持状态一致。 3)使用DI容器管理复杂依赖,提升代码质量和开发效率。

databasequeryOptimizationinphpinvolVolVOLVESEVERSEVERSTRATEMIESOENHANCEPERANCE.1)SELECTONLYNLYNESSERSAYCOLUMNSTORMONTOUMTOUNSOUDSATATATATATATATATATATRANSFER.3)


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Dreamweaver CS6
视觉化网页开发工具

Atom编辑器mac版下载
最流行的的开源编辑器