在PHP中使用cURL发布文件字符串?
我想知道,当文件只是一个字符串时,是否可以发布一个文件以及其他表单数据 我知道您可以通过在文件路径前面加“@”来发布文件系统中已经存在的文件 不过,我想绕过创建临时文件,只将文件作为字符串发送,但我不确定如何在PHP中使用cURL构造请求 干杯在PHP中使用cURL发布文件字符串?,php,file,post,upload,curl,Php,File,Post,Upload,Curl,我想知道,当文件只是一个字符串时,是否可以发布一个文件以及其他表单数据 我知道您可以通过在文件路径前面加“@”来发布文件系统中已经存在的文件 不过,我想绕过创建临时文件,只将文件作为字符串发送,但我不确定如何在PHP中使用cURL构造请求 干杯 $postFields = array( 'otherFields' => 'Yes' ,'filename' => 'my_file.csv' ,'data'
$postFields = array(
'otherFields' => 'Yes'
,'filename' => 'my_file.csv'
,'data' => 'comma seperated content'
);
$options = array(
CURLOPT_RETURNTRANSFER => true
,CURLOPT_SSL_VERIFYPEER => false
,CURLOPT_SSL_VERIFYHOST => 1
,CURLOPT_POSTFIELDS => $postFields
,CURLOPT_HTTPHEADER => array(
'Content-type: multipart/form-data'
)
);
应该是可能的:这是一个表单,通过浏览器发布(不相关字段省略): 因此,如果我们自己构建帖子主体并设置一个或两个额外的标题,我们应该能够模拟:
// form field separator
$delimiter = '-------------' . uniqid();
// file upload fields: name => array(type=>'mime/type',content=>'raw data')
$fileFields = array(
'file1' => array(
'type' => 'text/plain',
'content' => '...your raw file content goes here...'
), /* ... */
);
// all other fields (not file upload): name => value
$postFields = array(
'otherformfield' => 'content of otherformfield is this text',
/* ... */
);
$data = '';
// populate normal fields first (simpler)
foreach ($postFields as $name => $content) {
$data .= "--" . $delimiter . "\r\n";
$data .= 'Content-Disposition: form-data; name="' . $name . '"';
// note: double endline
$data .= "\r\n\r\n";
}
// populate file fields
foreach ($fileFields as $name => $file) {
$data .= "--" . $delimiter . "\r\n";
// "filename" attribute is not essential; server-side scripts may use it
$data .= 'Content-Disposition: form-data; name="' . $name . '";' .
' filename="' . $name . '"' . "\r\n";
// this is, again, informative only; good practice to include though
$data .= 'Content-Type: ' . $file['type'] . "\r\n";
// this endline must be here to indicate end of headers
$data .= "\r\n";
// the file itself (note: there's no encoding of any kind)
$data .= $file['content'] . "\r\n";
}
// last delimiter
$data .= "--" . $delimiter . "--\r\n";
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_POST, true);
curl_setopt($handle, CURLOPT_HTTPHEADER , array(
'Content-Type: multipart/form-data; boundary=' . $delimiter,
'Content-Length: ' . strlen($data)));
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
curl_exec($handle);
这样,我们就可以自己完成所有繁重的工作,并且相信cURL不会弄坏它。php可以访问临时位置“php://memory“,这实际上让你想做的事情变得相当容易
$fh = fopen('php://memory','rw');
fwrite( $fh, $content);
rewind($fh);
$options = array(
CURLOPT_RETURNTRANSFER => true
,CURLOPT_SSL_VERIFYPEER => false
,CURLOPT_SSL_VERIFYHOST => 1
,CURLOPT_HTTPHEADER => array(
'Content-type: multipart/form-data'
)
,CURLOPT_INFILE => $fh
,CURLOPT_INFILESIZE => strlen($content)
);
@Vin绝对不是复制品。这是个好问题。除了手工制作所有帖子数据之外,我不知道有什么方法可以添加部分标题。@Artefactor:是的,我没有正确理解这个问题,原始数据是指文件内容($path_to_file)?最初误读了这个问题,并理所当然地被否决了。我已经按照Piskvor的建议构建了这个请求,是的,你可以自己构建身体,它会起作用。尽管你必须100%准确地使用EOL。在“内容长度”和“内容处置”的末尾,需要双重返回。对于“Content Type:text/plain”之后的文件,还需要双返回。主体值的分隔符与“边界”中清除的分隔符也略有不同。每条边界线的开头都有两个额外的连字符。最后一个分隔符在开头和结尾有两个额外的催眠。@Chris Henry:的确如此。我建议你读一下这个问题;引用:“我知道您可以通过在文件路径前面加上“@”来发布文件系统中已经存在的文件。但是,我想绕过创建临时文件…”因此,“如何在没有@/some/file/name的情况下实现此目的?”的解决方案是“使用@/some/file/name”?在第一个
foreach
结尾填充$postFields
时,您会丢失$data.=$content。“\r\n”代码>否则将不发送字段内容。谢谢,@Piskvor!内容处置行中“name=”上的注释。它应该设置为元素的名称,该元素将在给定给CURLOPT_POSTFIELDS的数组中获得“@”文件。如果使用$params->file=“@myfilename.pdf”在curl_setopts CurlFile中设置文件,则需要name=“file”。我怀疑这与HTML中标记的“名称”相同。将其设置为与文件名相同可能不是服务器端想要的。这会允许与文件一起发送的其他postfields吗?它肯定会创建一个文件处理程序,我尝试了一下,但我认为CURLOPT_INFILE和CURLOPT_infiresize用于放置文件,$\u文件数组中未显示任何文件。问题中的代码可以一次上载多个文件。使用infle
也可以PUT
上传多个文件吗?为什么在行首加逗号?这是PHP,不是C,您可以用逗号结束所有项目<代码>[123456,]
$fh = fopen('php://memory','rw');
fwrite( $fh, $content);
rewind($fh);
$options = array(
CURLOPT_RETURNTRANSFER => true
,CURLOPT_SSL_VERIFYPEER => false
,CURLOPT_SSL_VERIFYHOST => 1
,CURLOPT_HTTPHEADER => array(
'Content-type: multipart/form-data'
)
,CURLOPT_INFILE => $fh
,CURLOPT_INFILESIZE => strlen($content)
);