First of all, $_FILES
is not populated when handling PUT requests. It is only populated by PHP when handling POST requests.
You need to parse it manually. That goes for "regular" fields as well:
// Fetch content and determine boundary
$raw_data = file_get_contents('php://input');
$boundary = substr($raw_data, 0, strpos($raw_data, "
"));
// Fetch each part
$parts = array_slice(explode($boundary, $raw_data), 1);
$data = array();
foreach ($parts as $part) {
// If this is the last part, break
if ($part == "--
") break;
// Separate content from headers
$part = ltrim($part, "
");
list($raw_headers, $body) = explode("
", $part, 2);
// Parse the headers list
$raw_headers = explode("
", $raw_headers);
$headers = array();
foreach ($raw_headers as $header) {
list($name, $value) = explode(':', $header);
$headers[strtolower($name)] = ltrim($value, ' ');
}
// Parse the Content-Disposition to get the field name, etc.
if (isset($headers['content-disposition'])) {
$filename = null;
preg_match(
'/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/',
$headers['content-disposition'],
$matches
);
list(, $type, $name) = $matches;
isset($matches[4]) and $filename = $matches[4];
// handle your fields here
switch ($name) {
// this is a file upload
case 'userfile':
file_put_contents($filename, $body);
break;
// default for all other files is to populate $data
default:
$data[$name] = substr($body, 0, strlen($body) - 2);
break;
}
}
}
At each iteration, the $data
array will be populated with your parameters, and the $headers
array will be populated with the headers for each part (e.g.: Content-Type
, etc.), and $filename
will contain the original filename, if supplied in the request and is applicable to the field.
Take note the above will only work for multipart
content types. Make sure to check the request Content-Type
header before using the above to parse the body.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…