此功能非常酷,并且在我的一种情况下都可以正常使用。
/**
*
* @param string $url
* @param array $params
* @return string
*/
public static function getUrlWithUpdatedParams($url, $params) {
$uri = \League\Uri\Http::createFromString($url);
$query = \League\Uri\Components\Query::createFromParams($params);
return \League\Uri\merge_query($uri, $query)->__toString();
}
我正在使用"league/uri": "^5.3"
(docs)。
这是我的测试,除最后一个测试外,所有断言均通过。
public function testGetUrlWithUpdatedParams() {
$this->assertEquals(url('/yo') . '?a=7', ST::getUrlWithUpdatedParams(url('/yo'), ['a' => 7]));
$this->assertEquals(url('/demo') . '?a=6&email=a@b.com', ST::getUrlWithUpdatedParams(url('/demo'), ['a' => 6, 'email' => 'a@b.com']));
$this->assertEquals(url('/sample') . '?ctrl=1&a=8', ST::getUrlWithUpdatedParams(url('/sample?ctrl=1'), ['a' => 8]));
$this->assertEquals(url('/sample') . '?ctrl=0&c=5', ST::getUrlWithUpdatedParams(url('/sample?ctrl=1'), ['c' => 5, 'ctrl' => 0]));
$this->assertEquals(url('/sample') . '?ctrl=1', ST::getUrlWithUpdatedParams(url('/sample?ctrl=1'), []));
$this->assertEquals(url('/sample') . '?ctrl=1', ST::getUrlWithUpdatedParams(url('/sample?ctrl=1'), ['ctrl' => null]));
$this->assertEquals(url('/sample') . '?ctrl=', ST::getUrlWithUpdatedParams(url('/sample?ctrl=1'), ['ctrl' => '']));
$encodedUrlAsParam = rawurlencode(url('/test'));
$this->assertEquals(url('/demo') . '?email_=a@b.com&url=' . $encodedUrlAsParam, ST::getUrlWithUpdatedParams(url('/demo'), ['email_' => 'a@b.com', 'url' => $encodedUrlAsParam])); //This one FAILS! Why in the world does getUrlWithUpdatedParams rawurlencode a second time??
}
我发现我可以通过 double rawurlen编码该参数来获得最终断言,如下所示:
$this->assertEquals(url('/demo') . '?email_=a@b.com&url=' . rawurlencode($encodedUrlAsParam), ST::getUrlWithUpdatedParams(url('/demo'), ['email_' => 'a@b.com', 'url' => $encodedUrlAsParam]));
但是,当我想从主URL检索URL param 时,然后再进行双重解码对我来说很奇怪。
发生了什么,如何避免这种情况?
答案 0 :(得分:0)
仅在将URL传递到getUrlWithUpdatedParams
之前不对其进行编码。我认为,这应该可行:
$qs = [
'email_' => 'a@b.com',
'url' => url('/test'),
];
$url = url('/demo');
$this->assertEquals($url.'?'.http_build_query($qs), ST::getUrlWithUpdatedParams($url, $qs));