Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中使用cURL发布文件字符串?_Php_File_Post_Upload_Curl - Fatal编程技术网

在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'

我想知道,当文件只是一个字符串时,是否可以发布一个文件以及其他表单数据

我知道您可以通过在文件路径前面加“@”来发布文件系统中已经存在的文件

不过,我想绕过创建临时文件,只将文件作为字符串发送,但我不确定如何在PHP中使用cURL构造请求

干杯

    $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)
);