What you want to do is in fact exactly the way that multipart messages work in relation to the $_POST
array.
Consider the following HTML form:
<form action="/somefile.php" method="post" enctype="multipart/form-data">
<input name="text1" type="text" />
<input name="text2" type="text" />
<input name="text3" type="text" />
<input name="file" type="file" />
<input type="submit" />
</form>
Now lets say we populate the three text inputs with value1
, value2
and value3
, we select a file called file.txt
, and press submit. This will result in a request that looks something like this:
POST /somefile.php HTTP/1.1
Host: somehost.com
Accept: */*
User-Agent: MyBrowser/1.0
Content-Type: multipart/form-data; boundary="this-is-a-boundary-string"
--this-is-a-boundary-string
Content-Dispostion: form-data; name="text1"
value1
--this-is-a-boundary-string
Content-Dispostion: form-data; name="text2"
value2
--this-is-a-boundary-string
Content-Dispostion: form-data; name="text3"
value3
--this-is-a-boundary-string
Content-Dispostion: form-data; name="file"; filename="file.txt"
Content-Type: text/plain
This is the contents of file.txt
--this-is-a-boundary-string--
When we look at it in PHP, if we print_r($_POST);
we should get something like this:
Array
(
[text1] => value1
[text2] => value2
[text3] => value3
)
...and if we print_r($_FILES);
:
Array
(
[file] => Array
(
[name] => file.txt
[type] => text/plain
[size] => 32
[tmp_name] => /tmp/dskhfwe43232.tmp
[error] => 0
)
)
...so you can see, the parts of the message where the Content-Disposition:
header does not contain a filename=""
element are added to the $_POST
array, and those with one are treated as file uploads and added to $_FILES
.
When building a multipart/form-data
message to send to a server, I find it easiest to build the HTML form that you are mimicking with the request, and construct your HTTP message based on how that HTML form would behave.