使用 file_get_contents 上传文件

新手上路,请多包涵

我知道我可以用 CURL 很容易地做到这一点,但我想知道是否可以使用 file_get_contents() 和 http 流上下文来将文件上传到远程 Web 服务器,如果可以,如何?

原文由 Shabbyrobe 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 725
1 个回答

首先, multipart Content-Type的第一条规则是 定义一个边界,作为每个部分之间的分隔符(因为顾名思义,它可以有多个部分)。边界可以是 _内容主体中未包含的任何字符串_。我通常会使用时间戳:

 define('MULTIPART_BOUNDARY', '--------------------------'.microtime(true));

定义边界后,您必须将它与 Content-Type 标头一起发送,以告诉网络服务器期望的分隔符:

 $header = 'Content-Type: multipart/form-data; boundary='.MULTIPART_BOUNDARY;

完成后,您必须构建一个与 HTTP 规范和您发送的标头相匹配的适当内容主体。如您所知,从表单发布文件时,您通常会有一个表单字段名称。我们将定义它:

 // equivalent to <input type="file" name="uploaded_file"/>
define('FORM_FIELD', 'uploaded_file');

然后我们构建内容主体:

 $filename = "/path/to/uploaded/file.zip";
$file_contents = file_get_contents($filename);

$content =  "--".MULTIPART_BOUNDARY."\r\n".
            "Content-Disposition: form-data; name=\"".FORM_FIELD."\"; filename=\"".basename($filename)."\"\r\n".
            "Content-Type: application/zip\r\n\r\n".
            $file_contents."\r\n";

// add some POST fields to the request too: $_POST['foo'] = 'bar'
$content .= "--".MULTIPART_BOUNDARY."\r\n".
            "Content-Disposition: form-data; name=\"foo\"\r\n\r\n".
            "bar\r\n";

// signal end of request (note the trailing "--")
$content .= "--".MULTIPART_BOUNDARY."--\r\n";

如您所见,我们正在发送 Content-Disposition 标头和 form-data 配置,以及 name 参数(66- 表单名称 filename 参数(原始文件名)。如果要正确填充 $_FILES[]['type'] 东西,发送具有正确 MIME 类型的 Content-Type 标头也很重要。

如果您有多个文件要上传,您只需使用 $content 位重复该过程,当然,每个文件都有不同的 FORM_FIELD

现在,构建上下文:

 $context = stream_context_create(array(
    'http' => array(
          'method' => 'POST',
          'header' => $header,
          'content' => $content,
    )
));

并执行:

 file_get_contents('http://url/to/upload/handler', false, $context);

注意: 发送前无需对二进制文件进行编码。 HTTP 可以很好地处理二进制文件。

原文由 netcoder 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏