繁体   English   中英

多部分请求时Fosrestbundle正空

[英]Fosrestbundle body empty when multipart request

在下面的代码中,我希望$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测试,当使用PostmanAdvanced Rest Client模拟请求时,身体似乎再次为空。 我仔细检查了这个以使用调试器将模拟请求作为PHPUnit运行。 实际上,当通过Rest客户端模拟时,正文是空的,而当通过PHPUnit运行时,正文是空的。

我使用的测试用例:

POST网址:

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.net上的php:// wrappers:

注意:在PHP 5.6之前,使用php://输入打开的流只能读取一次; 流不支持搜索操作。 但是,根据SAPI实现,可能会打开另一个php://输入流并重新开始读取。 只有在保存了请求正文数据后才能执行此操作。 通常,这是POST请求的情况,但不是其他请求方法,例如PUT或PROPFIND。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM