php 使用 file_get_contents 上传文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4003989/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 11:42:36  来源:igfitidea点击:

Upload a file using file_get_contents

phpfile-uploadfile-get-contents

提问by Shabbyrobe

I realise I can do this with CURL very easily, but I was wondering if it was possible to use file_get_contents()with the http stream context to upload a file to a remote web server, and if so, how?

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

回答by netcoder

First of all, the first rule of multipartContent-Type is to define a boundarythat will be used as a delimiter between each part (because as the name says, it can have multiple parts). The boundary can be any string that is not contained in the content body. I will usually use a timestamp:

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

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

Once your boundary is defined, you must send it with the Content-Typeheader to tell the webserver what delimiter to expect:

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

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

Once that is done, you must build a proper content body that matches the HTTP specification and the header you sent. As you know, when POSTing a file from a form, you will usually have a form field name. We'll define it:

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

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

Then we build the content body:

然后我们构建内容主体:

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

As you can see, we're sending the Content-Dispositionheader with the form-datadisposition, along with the nameparameter (the form field name) and the filenameparameter (the original filename). It is also important to send the Content-Typeheader with the proper MIME type, if you want to correctly populate the $_FILES[]['type']thingy.

如您所见,我们正在发送Content-Disposition带有form-data处置的标头,以及name参数(表单字段名称)和filename参数(原始文件名)。Content-Type如果您想正确填充$_FILES[]['type']事物,那么使用正确的 MIME 类型发送标头也很重要。

If you had multiple files to upload, you just repeat the process with the $contentbit, with of course, a different FORM_FIELDfor each file.

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

Now, build the context:

现在,构建上下文:

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

And execute:

并执行:

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

NOTE:There is no need to encode your binary file before sending it. HTTP can handle binary just fine.

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