Why pass an array in a URL? And why is it not as simple as it seems?
\nImagine: you are writing a PHP product filter for an online store. A user selects several categories, several colors, and a price range. How do you pass all this data to the server via a GET request? The obvious solution is ?category=1&category=2&category=3. But the server will only see the last value, unless you use a trick.
On Stack Overflow, the question "How to pass an array within a query string?" has gathered tens of thousands of views. Developers stumble on this every day. Today we will break down this topic from start to finish: I will show you how to properly pass an array via a URL, how to handle it on the server, and what pitfalls await you.
\nReady to turn chaotic GET parameters into a well-structured data format? Let's go!
\n\nBasics: How PHP handles a query string
\nWhen you send a GET request, PHP automatically populates the superglobal array $_GET. If the URL contains ?name=John&age=25, then $_GET will look like this:
array(2) {\n ["name"] => string(4) "John"\n ["age"] => string(2) "25"\n}\nBut what if we try to pass multiple values with the same key? Let's write a URL: ?color=red&color=green&color=blue. The server will only receive color=blue. The other values will be overwritten because PHP doesn't know what to do with duplicate keys.
This is where the square bracket syntax comes to the rescue, which was designed specifically for this task.
\n\nMethod #1: Square bracket syntax (most popular)
\nAdd square brackets to the parameter name: color[]. When PHP sees this pattern, it automatically creates an array. Example URL:
?color[]=red&color[]=green&color[]=blue\nOn the server, $_GET will contain:
array(1) {\n ["color"] => array(3) {\n [0] => string(3) "red"\n [1] => string(5) "green"\n [2] => string(4) "blue"\n }\n}\nAnd here is an example of PHP code that handles this:
\n<?php\n// URL: example.com?color[]=red&color[]=green&color[]=blue\nif (isset($_GET['color']) && is_array($_GET['color'])) {\n echo "Selected colors:<br>";\n foreach ($_GET['color'] as $index => $color) {\n echo ($index + 1) . ". " . htmlspecialchars($color) . "<br>";\n }\n}\n?>\nResult in the browser:
\nSelected colors:\n1. red\n2. green\n3. blue\n\nNamed keys: when order doesn't matter
\nSometimes you need to pass an associative array (key → value). For this, use the key[] syntax with a specified key:
?filter[category]=books&filter[price]=100&filter[in_stock]=1\nPHP will turn this into:
\narray(1) {\n ["filter"] => array(3) {\n ["category"] => string(5) "books"\n ["price"] => string(3) "100"\n ["in_stock"] => string(1) "1"\n }\n}\nServer-side handling:
\n<?php\nif (isset($_GET['filter'])) {\n $filter = $_GET['filter'];\n $query = "SELECT * FROM products WHERE 1=1";\n if (!empty($filter['category'])) {\n $query .= " AND category = '" . mysqli_real_escape_string($conn, $filter['category']) . "'";\n }\n if (!empty($filter['price'])) {\n $query .= " AND price <= " . (int)$filter['price'];\n }\n // ... remaining conditions\n}\n?>\n\nMethod #2: JSON in query string (advanced)
\nIf the array is complex (deeply nested), the square bracket syntax becomes cumbersome. An alternative is to pass a JSON string in URL-encoded form.
\nForming the URL on the client side (JavaScript):
\nconst data = {\n colors: ['red', 'green', 'blue'],\n sizes: ['S', 'M', 'L'],\n options: {\n gift_wrap: tr