Почему rawurlencode требуется дважды здесь? - PullRequest
0 голосов
/ 09 декабря 2018

Эта функция довольно крутая и хорошо работает во всех, кроме одной моей ситуации.

/**
 * 
 * @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" ( документы ).

Вот мои тесты, в которых все утверждения проходят, кроме последнего.

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 rawurlencoding для параметра выглядит следующим образом:

$this->assertEquals(url('/demo') . '?email_=a@b.com&url=' . rawurlencode($encodedUrlAsParam), ST::getUrlWithUpdatedParams(url('/demo'), ['email_' => 'a@b.com', 'url' => $encodedUrlAsParam]));

Но мне кажется странным, что потом будет двойное декодирование, когда я хочу получить URL param из основного URL.

Что происходит, и как мне этого избежать?

1 Ответ

0 голосов
/ 09 декабря 2018

Только не кодируйте URL, прежде чем передавать его на getUrlWithUpdatedParams.Я думаю, это должно работать:

$qs = [
    'email_' => 'a@b.com',
    'url' => url('/test'),
];

$url = url('/demo');
$this->assertEquals($url.'?'.http_build_query($qs), ST::getUrlWithUpdatedParams($url, $qs));
...