Мне было поручено создать API для существующего мобильного приложения. Приложение отправляет составные данные и файлы в одном запросе PUT. В качестве примера, существует конечная точка PUT / api / employee / personal-info (обратите внимание на отсутствие идентификатора в URI), которая является составной частью - данные JSON и 2 изображения.
PHP не имеет встроенной поддержки PUT, он не очень хорошо помещает все в $ _FILES и $ _POST, поэтому мне приходится декодировать ввод вручную.
Сначала мне нужно сделать file_get_contents("php://input"), который дает мне необработанные данные. Мне нужно использовать регулярное выражение для извлечения граничной строки, затем мне нужно разделить ввод на блоки, используя эту границу (и снова регулярное выражение), а затем решить, является ли блок JSON или файлом, просмотрев Content-Disposition на каждом из блоки. Если это файл, мне нужно повторно определить имя файла и расширение, а также вручную заполнить массив $ _FILES.
У блоков Json есть эти заголовки (внутри тела, непосредственно перед фактическими данными)
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=model
а файловые блоки имеют только это:
Content-Disposition: form-data; name=file; filename=IMG_20180208_1.jpg; filename*=utf-8’’IMG_20180208_1.jpg
Таким образом, Content-Disposition для всего ввода - это multipart / form-data, но тогда каждый из блоков имеет свои собственные заголовки, в зависимости от того, является ли это файлом или данными JSON.
Неужели это единственный способ сделать это в PHP? Должны ли конечные точки PUT НЕ быть, как правило, составными, когда дело доходит до PHP? Я что-то пропустил?
Есть ли какие-то основные правила того, какие заголовки должны быть включены в каждый блок и должны ли они иметь определенный формат? Когда вы смотрите на те, что в вопросе, нет кавычек вокруг имени файла и т. д., Почтальон выплевывает заголовки, немного отличающиеся от тех, которые я получаю из приложения.
Существуют «основные правила» с точки зрения спецификаций RFC (см. Ссылки из developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…), но, как вы видели, пользовательские агенты могут игнорировать спецификации и игнорируют их. Предположительно вы создаете частный API для этого приложения, поэтому я бы работал с тем, что приложение уже отправляет, а не в строгом соответствии со спецификациями.
@ Грэм, ясно. Я бы подумал, что существуют определенные строгие правила, касающиеся синтаксиса HTTP-запросов и т. д. Но потом я также подумал, что в PHP будет поддержка PUT, аналогичная поддержке POST. Я ни в коем случае не старший разработчик, но это застало меня врасплох. В конце концов мне удалось написать класс, который декодирует и разбивает ввод на блоки, а затем помещает все в соответствующие массивы, сохраняет несколько файлов и т. д., Но это было мучительно ... Ребята из .NET в офисе сказали, что им никогда не приходилось иметь дело с эта проблема и я завидую.






Я бы сказал, что отсутствие поддержки PUT в PHP не делает идею составной PUT менее актуальной; да, это чертовски раздражает, и это означает, что вам придется написать какой-то уродливый код синтаксического анализа, но с точки зрения приложения это разумная вещь.