使用file_get_contents上传文件 [英] Upload a file using file_get_contents

查看:622
本文介绍了使用file_get_contents上传文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我意识到我可以很容易地用CURL来做到这一点,但是我想知道是否可以使用 file_get_contents()和http流上下文来上传文件一个远程web服务器,如果是这样的话,怎么样?

解决方案

首先, multipart Content-Type是定义一个边界,用作每个部分之间的分隔符(因为名称可以有多个部分)。边界可以是任何不包含在内容体内的字符串。我通常会使用一个时间戳:

  define('MULTIPART_BOUNDARY','------------ -------------- microtime中(真)); 

定义边界后,您必须使用 Content-Type

标题告诉网络服务器预期的分隔符:

  $ header ='Content-Type:multipart /格式数据;边界= MULTIPART_BOUNDARY。 

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

  //相当于< input type =filename =uploaded_file/> 
define('FORM_FIELD','uploaded_file');

然后我们建立内容主体:

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

$ content = - 。MULTIPART_BOUNDARY。\r\\\

Content-Disposition:form-data; name = \。FORM_FIELD。\; filename = \。basename($ filename)。\\r\\\

Content-Type:application / zip\r\\\
\r\\\

$ file_contents。\r\\\
;

//向请求添加一些POST字段:$ _POST ['foo'] ='bar'
$ content。= - 。MULTIPART_BOUNDARY。\r\\ \

Content-Disposition:form-data; name = \foo \\r\\\
\r\\\

bar \r\\\
;

//请求结束(注意结尾的 - )
$ content。= - 。MULTIPART_BOUNDARY。 - \r\\\
;

正如您所看到的,我们正在发送 Content-Disposition form-data 处置的code>头,以及名称参数(表单字段名称)和 filename 参数(原始文件名)。如果要正确填充 $ _ FILES [] ['类型,则发送带有适当MIME类型的 Content-Type '] thingy。



如果您有多个要上传的文件,只需使用 $ 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可以很好地处理二进制文件。


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?

解决方案

First of all, the first rule of multipart Content-Type is to define a boundary that 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:

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

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

$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:

// 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-Disposition header with the form-data disposition, along with the name parameter (the form field name) and the filename parameter (the original filename). It is also important to send the Content-Type header with the proper MIME type, if you want to correctly populate the $_FILES[]['type'] thingy.

If you had multiple files to upload, you just repeat the process with the $content bit, with of course, a different FORM_FIELD for each file.

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.

这篇关于使用file_get_contents上传文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆