哪位大侠有使用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提供下载.
不错!!!!!!
我也要一份

TheSecretTokeEpingAphp-PowerEdwebSiterUnningSmoothlyShyunderHeavyLoadInVolvOLVOLVOLDEVERSALKEYSTRATICES:1)emplactopCodeCachingWithOpcachingWithOpCacheToreCescriptexecution Time,2)使用atabasequercachingCachingCachingWithRedataBasEndataBaseLeSendataBaseLoad,3)

你應該關心DependencyInjection(DI),因為它能讓你的代碼更清晰、更易維護。 1)DI通過解耦類,使其更模塊化,2)提高了測試的便捷性和代碼的靈活性,3)使用DI容器可以管理複雜的依賴關係,但要注意性能影響和循環依賴問題,4)最佳實踐是依賴於抽象接口,實現鬆散耦合。

是的,優化papplicationispossibleandessential.1)empartcachingingcachingusedapcutorediucedsatabaseload.2)優化的atabaseswithexing,高效Quereteries,and ConconnectionPooling.3)EnhanceCodeWithBuilt-unctions,避免使用,避免使用ingglobalalairaiables,並避免使用

theKeyStrategiestosigantificallyBoostPhpaPplicationPerformenCeare:1)UseOpCodeCachingLikeLikeLikeLikeLikeCacheToreDuceExecutiontime,2)優化AtabaseInteractionswithPreparedStateTementStatementStatementAndProperIndexing,3)配置

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)


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。