Closed
Description
Description
I and probably a hand full of developers wasted hours debugging on why file uploads with PUT requests don't work. After finally ending up at https://www.php.net/manual/en/features.file-upload.put-method.php, it seems like PHP handled file uploads on PUT requests differently.
Example
I think it would be a great addition to the Request class to accommodate for this in the $request->files
FileBag.
Current Situation
Here some awful code that showcases the current situation:
public function getUploadedFilesFromBody(): array
{
// Try finding in PHP PUT content.
// https://www.php.net/manual/en/features.file-upload.put-method.php
$putdata = fopen("php://input", "r");
$uploadedFiles = [];
$temporaryFilePointer = null;
$tmpFileName = null;
$header = false;
$fileKey = null;
$fileName = null;
$mimeType = null;
$currentBoundary = null;
while (false !== ($line = fgets($putdata))) {
$webkitFormBoundaryFlag = substr($line, 0, 24) === '------WebKitFormBoundary';
if (false === $header && $webkitFormBoundaryFlag) {
$header = true;
// Check on current file
$currentBoundary = trim(substr($line, 24));
// Read header information.
$contentDisposition = fgets($putdata);
if (false === $contentDisposition || 'Content-Disposition' !== substr($contentDisposition, 0, 19)) {
// Wrong format.
break;
}
$fileKeyGroups = [];
$status = preg_match('/\ name=\"(?P<file>[\w\.]*)\"/', $contentDisposition, $fileKeyGroups);
if (0 === $status) {
// Could not extract name
break;
}
$fileKey = $fileKeyGroups['file'];
$fileNameGroups = [];
$status = preg_match('/\ filename=\"(?P<filename>[\w\.]*)\"/', $contentDisposition, $fileNameGroups);
if (0 === $status) {
// Could not extract filename
break;
}
$fileName = $fileNameGroups['filename'];
$contentType = fgets($putdata);
if (false === $contentType) {
// Wrong format.
break;
}
$mimeType = substr($contentType, strlen('Content-Type: '));
$skip = fgets($putdata);
if (false === $skip) {
break;
}
$tmpFileName = tempnam(sys_get_temp_dir(), 'media_object_put_');
$temporaryFilePointer = fopen($tmpFileName, "w");
} elseif (true === $header && $webkitFormBoundaryFlag) {
$headerEnd = substr($line, 24 + strlen($currentBoundary), 2) === '--';
if ($headerEnd) {
$header = false;
// Create a UploadedFile.
$uploadedFiles[$fileKey] = new UploadedFile($tmpFileName, $fileName, $mimeType);
fclose($temporaryFilePointer);
}
} else {
fwrite($temporaryFilePointer, $line);
}
}
fclose($putdata);
return $uploadedFiles;
}