user1392897
user1392897

Reputation: 851

Symfony HttpClient GET request with multiple query string parameters with same name

I am trying to make an API request in the following format:

/api/v1/courses?enrollment_state=active&include[]=total_students&include[]=term

How can I do so using the HttpClient Component query string parameters?

$response = $client->request('GET', '/api/v1/courses', [
      'query' => [
           'enrollment_state' => 'active',
           'include[]' => 'term',
           'include[]' => 'total_students',
       ],
]);

As the above approach does not work due to duplicate array key?

I have also tried:

'include[]' => ['term', 'total_students']

Upvotes: 4

Views: 6323

Answers (2)

Julien
Julien

Reputation: 749

as @user1392897 says, @yivi snippet returns indexes in the url query string.

https://www.example.com/?foo[0]=bar&foo[1]=baz

That's because it use the http_build_query built in function and it's the function behaviour. You can read this thread php url query nested array with no index about it.

A workaround it to build the query string yourself from the array and append it to your url, the the 2nd parameter of the HttpClient->request() method.

function createQueryString(array $queryArray = []): ?string
{
    $queryString = http_build_query($queryArray, '', '&', \PHP_QUERY_RFC3986);
    $queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $queryString); //foo[]=x&foo[]=y
    
    return '' !== $queryString ? $queryString : null;
}

$queryArray = [
    'abc' => ['one', 'two']
];

$queryString = createQueryString($queryArray);

$url = 'https://www.example.com/';
if (is_string($queryString)) {
    $url = sprintf('%s?%s', $url, $queryString);
}

$response = $client->request('GET', $url);

Upvotes: 0

yivi
yivi

Reputation: 47329

To create the equivalent to:

https://www.example.com/?token=foo&abc[]=one&abc[]=two

Just do:

$client->request(
    'GET',
    'https://www.example.com/',
    [
        'query' => [
            'token' => 'foo',
            'abc' => ['one', 'two']
        ]
    ]
);

Upvotes: 5

Related Questions