在下面的代码中,我期望$request->getContents()获得HTTP请求的主体内容。当发送非多部分请求时,这会像预期的那样工作,尽管在使用multipart请求时,$body变量仍然是空的。
public function postDebugAction(Request $request) {
$body = $request->getContent();
if (empty($body)) {
throw new \Exception('Body empty.');
}
return $this->view(array(), 201);
}在阅读了this问答之后,我还添加了一个body侦听器。
<?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运行时则不是空的。
我使用的测试用例:
贴图网址:
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--UPDATE I不确定我是否在没有使用BodyListener的情况下通过调试器。当我这么做的时候,结果完全一样。因此,没有BodyListener,虽然模拟请求仍然是空的,但PHPUnit大小写得到了主体。
发布于 2015-10-29 16:50:28
请参见php://包装器在php.net上:
注意:在PHP5.6之前,使用php://input打开的流只能读取一次;该流不支持查找操作。但是,根据SAPI实现,可能会打开另一个php://input流并重新启动读取。只有在保存了请求正文数据时,才有可能这样做。通常,POST请求就是这种情况,而不是其他请求方法,例如PUT或PROPFIND。
因此,更新您的PHP版本,或确保您只读取输入一次。
发布于 2018-02-08 13:24:50
在$request->files->all()解码后,您可以在fos_rest.decoder_provider中找到上传的文件。
https://stackoverflow.com/questions/28781823
复制相似问题