Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

EMax's avatar
Level 1

Query parameter with same name but different values without brackets=

I currently have the task of consuming some data from an API. Current implementation requires filtering by query paramters, however to filter for a subset of persons you have to add the same query parameters multiple times with different values

API DOC: https://developer.personio.de/reference/get_v2-attendance-periods.

URI for a request would have to look like this: https://api.personio.de/v2/attendance-periods?person.id=1&person.id=2

However when i use the Http Facade with the withQueryParameters method, I logically cannot put multiple values for the same query param. If i pass the array of user ids to the query param the resulting query paramaters in the URI will have the array indexes listed and the URI will be created like so: https://api.personio.de/v2/attendance-periods?person.id[0]=1&person.id[1]=2.

Does anyone have a clue how to create query parameters with same name but different values?

0 likes
2 replies
Glukinho's avatar

No standard way comes to mind, all PHP URL query builders work with arrays, which don't allow having multiple identical keys. This makes sense for me, and I'd call this API realization wrong and bad.

There is always a dirty way, construct a query by yourself and strip out brackets and sequential numbers:

$data = [
	'person.id' => [1, 2, 3],
	'limit'     => 100,
];

$query_string = Str::of(http_build_query($data))
	->replaceMatches('/%5B[0-9]+%5D/', '')
	->toString();

Http::get('https://api.personio.de/v2/attendance-periods', $query_string); 

// request goes to: https://api.personio.de/v2/attendance-periods?person.id=1&person.id=2&person.id=3&limit=100
krisi_gjika's avatar

you may have to build the url yourself and pass it as whole

$url = 'https://api.personio.de/v2/attendance-periods';
$filters = [
    'limit' => 100,
    'id' => '',
    'person.id' => [123, 123],
    'status' => 'PENDING',
];

if (filled($filters)) {
  $url .= '?';
  foreach ($filters as $key => $value) {
    if (is_array($value)) {
       foreach ($value as $v) {
         $url .= $key.'='.urlencode($v);
       }
    } else {
      $url .= $key.'='.$value;
    }
    
    $url .= '&';
  }
  
  $url = rtrim($url, '&');
}

Please or to participate in this conversation.