0

我正在处理这个新的Zend Framework 版本。如手册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 作为供应商通过composerwith安装require "zendframework/zend-http": "2.0.6"。在PHP 5.4.9PHP 5.3.10

这是一个错误还是我错过了什么?

谢谢。

4

1 回答 1

0

很难说它是否是一个错误。然而,行为似乎不一致或至少不直观。这是可以按预期工作的示例:

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()方法不能优雅地处理这两种情况。

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

如果您想将表单字段保留为对象,则必须自己创建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 建议 - B.2.2 URI 属性值中的与号

于 2013-01-05T03:03:21.920 回答