200分求助CURL设置HTTPHEADER上传文件问题!
哪位大侠有使用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 = <<< TEXT
$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 =<<< 'TEXT'
数据报中应该是
Content-Disposition: form-data; name="userfile"; filename="file_name"
Content-Type: 文档类型
文件内容
这样的格式
以下是服务器端代码
curl_upload_server.php
print_r(……
没有client?
完整的代码PHP code
$contents =<<< 'TEXT'
数据报中应该是
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提供下载.
不错!!!!!!
我也要一份

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Alipay PHP ...

세션 납치는 다음 단계를 통해 달성 할 수 있습니다. 1. 세션 ID를 얻으십시오. 2. 세션 ID 사용, 3. 세션을 활성 상태로 유지하십시오. PHP에서 세션 납치를 방지하는 방법에는 다음이 포함됩니다. 1. 세션 _regenerate_id () 함수를 사용하여 세션 ID를 재생산합니다. 2. 데이터베이스를 통해 세션 데이터를 저장하십시오.

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

PHP 개발에서 견고한 원칙의 적용에는 다음이 포함됩니다. 1. 단일 책임 원칙 (SRP) : 각 클래스는 하나의 기능 만 담당합니다. 2. Open and Close Principle (OCP) : 변경은 수정보다는 확장을 통해 달성됩니다. 3. Lisch의 대체 원칙 (LSP) : 서브 클래스는 프로그램 정확도에 영향을 미치지 않고 기본 클래스를 대체 할 수 있습니다. 4. 인터페이스 격리 원리 (ISP) : 의존성 및 사용되지 않은 방법을 피하기 위해 세밀한 인터페이스를 사용하십시오. 5. 의존성 반전 원리 (DIP) : 높고 낮은 수준의 모듈은 추상화에 의존하며 종속성 주입을 통해 구현됩니다.

phpstorm에서 CLI 모드를 디버그하는 방법은 무엇입니까? PHPStorm으로 개발할 때 때때로 CLI (Command Line Interface) 모드에서 PHP를 디버그해야합니다 ...

시스템이 다시 시작된 후 UnixSocket의 권한을 자동으로 설정하는 방법. 시스템이 다시 시작될 때마다 UnixSocket의 권한을 수정하려면 다음 명령을 실행해야합니다.

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

PHP 개발에서 PHP의 CURL 라이브러리를 사용하여 JSON 데이터를 보내면 종종 외부 API와 상호 작용해야합니다. 일반적인 방법 중 하나는 컬 라이브러리를 사용하여 게시물을 보내는 것입니다 ...
