Zend \ Http \ Request在带有post值的toString()中失败

时间:2013-01-04 13:17:47

标签: php zend-framework2

我正在处理这个新的 Zend Framework版本。如manual页面所示,我希望返回toString() POST 内容:

use Zend\Http\Request;

class RequestTest extends \PHPUnit_Framework_TestCase
{
    public function testARequestWithAPostValue()
    {
        $request = new Request();
        $request->setMethod(Request::METHOD_POST);
        $request->setUri('/foo');
        $request->getPost()->set('foo', 'bar');

        $string = "POST /foo HTTP/1.1\r\n\r\nfoo=bar&";
        $this->assertEquals($string, $request->toString());
    }
}

但该地区似乎是空的:

1) RequestTest::testRequestWithAPostValue
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
 'POST /foo HTTP/1.1

-foo=bar&'
+'

Zend Framework 2由composerrequire "zendframework/zend-http": "2.0.6"作为供应商安装。这两者都在PHP 5.4.9PHP 5.3.10

那是错误还是我错过了什么?

感谢。

1 个答案:

答案 0 :(得分:0)

很难说它是不是一个bug。但是,行为似乎不一致或至少不直观。以下是可以按预期工作的示例:

use Zend\Http\Request;

class RequestTest extends \PHPUnit_Framework_TestCase
{
    public function testARequestWithAPostValue()
    {
        $string = "POST /foo HTTP/1.1\r\n\r\nfoo=bar;bar=foo";
        $request = Request::fromString($string);

        $this->assertEquals($string, $request->toString());
    }
}

回复$ request将输出:

POST /foo HTTP/1.1

foo=bar;bar=foo

方法命名,文档和预期用法令人困惑:表单字段可以存储为原始字符串或对象参数。方法 Request :: toString()不能正常处理这两种情况。

从sting创建 Request 对象时,表单字段将使用 Request :: setContent()方法存储为原始字符串。在调用 Request :: toString()方法时,将在编写 Request 的字符串表示时调用 Request :: getContent()方法对象;

如果您希望将表单字段保留为对象,则必须自己创建 Request 对象的字符串表示形式。

use Zend\Http\Request;
use Zend\Stdlib\Parameters;

class RequestTest extends \PHPUnit_Framework_TestCase
{
    public function testARequestWithAPostValue()
    {
        $request = new Request();
        $request->setMethod(Request::METHOD_POST);
        $request->setUri('/foo');
        $params = new Parameters();
        $params->set('foo', 'bar');
        $params->set('bar', 'foo');
        $request->setPost($params);

        $str = $request->renderRequestLine() . "\r\n";
        $headers = $request->getHeaders();
        if (!empty($headers)):
            $str .= $headers->toString();
        endif;
        $str .= "\r\n";

        $rawData = '';
        $keys = array_keys($params->toArray());
        foreach ($keys as $name) :
            $rawData .= "$name=" . $request->getPost($name) . ";";
        endforeach;
        $str .= substr($rawData, 0, -1);

        $string = "POST /foo HTTP/1.1\r\n\r\nfoo=bar;bar=foo";
        $this->assertEquals($string, $str);
    }
}

请注意,在最后一个表单字段键值对之后没有分隔符。

使用“&”分隔表单字段的字符被认为是一种不好的做法。请参阅W3C Recommendations - B.2.2 Ampersands in URI attribute values