首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当多部分请求时Fosrestbundle主体为空

当多部分请求时Fosrestbundle主体为空
EN

Stack Overflow用户
提问于 2015-02-28 12:42:25
回答 2查看 1.4K关注 0票数 3

在下面的代码中,我期望$request->getContents()获得HTTP请求的主体内容。当发送非多部分请求时,这会像预期的那样工作,尽管在使用multipart请求时,$body变量仍然是空的。

代码语言:javascript
复制
public function postDebugAction(Request $request) {
    $body = $request->getContent();

    if (empty($body)) {
        throw new \Exception('Body empty.');
    }


    return $this->view(array(), 201);
}

在阅读了this问答之后,我还添加了一个body侦听器。

代码语言:javascript
复制
<?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测试,虽然在使用PostmanAdvanced Rest Client模拟请求时,这是有效的,但是身体似乎又是空的。我对此进行了双重检查,以便在调试器中以PHPUnit的形式运行两个模拟请求。结果是,实际上,当通过Rest客户机模拟时,身体是空的,而在通过PHPUnit运行时则不是空的。

我使用的测试用例:

贴图网址:

代码语言:javascript
复制
http://localhost/EntisServer/web/app_dev.php/api2/debug

标题:

代码语言:javascript
复制
Authorization: Bearer ZGYzYjY1YzY4MGY3YWM3OTFhYTI4Njk3ZmI0NmNmOWZmMjg5MDFkYzJmOWZkOWE4ZTkyYTRmMGM4NTE1MWM0Nw
Content-Type: multipart/form-data; boundary=-----XXXXX

内容:

代码语言:javascript
复制
-----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大小写得到了主体。

EN

回答 2

Stack Overflow用户

发布于 2015-10-29 16:50:28

请参见php://包装器在php.net上:

注意:在PHP5.6之前,使用php://input打开的流只能读取一次;该流不支持查找操作。但是,根据SAPI实现,可能会打开另一个php://input流并重新启动读取。只有在保存了请求正文数据时,才有可能这样做。通常,POST请求就是这种情况,而不是其他请求方法,例如PUT或PROPFIND。

因此,更新您的PHP版本,或确保您只读取输入一次。

票数 0
EN

Stack Overflow用户

发布于 2018-02-08 13:24:50

$request->files->all()解码后,您可以在fos_rest.decoder_provider中找到上传的文件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28781823

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档