В коде ниже я ожидаю $request->getContents()
чтобы получить содержание тела HTTP
запрос. При отправке не составного запроса это работает, как и ожидалось, хотя при использовании составных запросов $body
переменная остается пустой.
public function postDebugAction(Request $request) {
$body = $request->getContent();
if (empty($body)) {
throw new \Exception('Body empty.');
}return $this->view(array(), 201);
}
После прочтения этот вопрос и ответ я добавил тело слушателя, а также.
<?php
namespace VSmart\ApiBundle\Listener;
use FOS\RestBundle\EventListener\BodyListener as BaseBodyListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use FOS\RestBundle\Decoder\DecoderProviderInterface;
class BodyListener extends BaseBodyListener {
/**
* @var DecoderProviderInterface
*/
private $decoderProvider;
/**
* @param DecoderProviderInterface $decoderProvider Provider for fetching decoders
*/
public function __construct(DecoderProviderInterface $decoderProvider) {
$this->decoderProvider = $decoderProvider;
}
/**
* {@inheritdoc}
*/
public function onKernelRequest(GetResponseEvent $event) {
$request = $event->getRequest();
if (strpos($request->headers->get('Content-Type'), 'multipart/form-data') !== 0) {
return;
}
$format = 'json';
if (!$this->decoderProvider->supports($format)) {
return;
}
$decoder = $this->decoderProvider->getDecoder($format);
$iterator = $request->request->getIterator();
$request->request->set($iterator->key(), $decoder->decode($iterator->current(), $format));
}
}
Согласно моему тесту PHPUnit это работало, хотя при использовании Postman
а также Advanced Rest Client
для имитации запроса тело снова кажется пустым. Я дважды проверил это, чтобы запустить оба имитирующих запроса как PHPUnit с отладчиком. В результате, на самом деле тело пусто при моделировании через клиент Rest и не пусто при запуске через PHPUnit.
Тестовый пример, который я использовал:
POST URL:
http://localhost/EntisServer/web/app_dev.php/api2/debug
Заголовки:
Authorization: Bearer ZGYzYjY1YzY4MGY3YWM3OTFhYTI4Njk3ZmI0NmNmOWZmMjg5MDFkYzJmOWZkOWE4ZTkyYTRmMGM4NTE1MWM0Nw
Content-Type: multipart/form-data; boundary=-----XXXXX
Содержание:
-----XXXXX
Content-Disposition: form-data; name="json"Content-Type: application/json; charset=utf-8
{
"blabla": 11
}
-----XXXXX
Content-Disposition: form-data; name="q_3101"; filename="image.jpg"Content-Type: image/jpeg
contents of a file...
-----XXXXX--
ОБНОВИТЬ
Я был не уверен, прошел ли я отладчик без использования BodyListener
, Когда я сделал, результат точно такой же. Итак, без BodyListener
случай PHPUnit получает тело, хотя моделируемый запрос все еще пуст.
Увидеть php://
фантики на php.net:
Примечание: до PHP 5.6 поток, открытый с помощью php: // input, мог быть прочитан только один раз; поток не поддерживает операции поиска. Однако, в зависимости от реализации SAPI, может быть возможно открыть другой поток ввода php: // и возобновить чтение. Это возможно только в том случае, если данные тела запроса были сохранены. Как правило, это касается запросов POST, но не других методов запроса, таких как PUT или PROPFIND.
Поэтому обновите версию PHP или убедитесь, что вы читаете ввод только один раз.
Вы можете найти ваши загруженные файлы в $request->files->all()
после fos_rest.decoder_provider
декодирования.