为什么要在 URL 中传递数组?为什么这并不像看起来那么简单?
\n想象一下:您正在用 PHP 为电商网站编写一个商品筛选器。用户选择了多个类别、多种颜色和一个价格范围。如何通过 GET 请求将所有数据传递给服务器?显而易见的解决方案是 ?category=1&category=2&category=3。但是,如果不使用技巧,服务器只会看到最后一个值。
在 Stack Overflow 上,"How to pass an array within a query string?" 这个问题已经获得了数万次浏览。开发人员每天都会在这里遇到困难。今天,我们将从头到尾讨论这个主题:我将展示如何通过 URL 正确传递数组,如何在服务器端处理它,以及您会遇到哪些陷阱。
\n准备好将混乱的 GET 参数转换为结构化的数据结构了吗?我们开始吧!
\n\n基础知识:PHP 如何处理查询字符串
\n当您发送 GET 请求时,PHP 会自动填充超全局数组 $_GET。如果 URL 中包含 ?name=John&age=25,那么 $_GET 将如下所示:
array(2) {\n ["name"] => string(4) "John"\n ["age"] => string(2) "25"\n}\n但是,如果我们尝试传递多个具有相同键的值呢?我们编写 URL:?color=red&color=green&color=blue。服务器只会收到 color=blue。其他值将被覆盖,因为 PHP 不知道如何处理重复的键。
这时,方括号语法就派上用场了,它正是为此任务而设计的。
\n\n方法 #1:方括号语法(最流行)
\n在参数名称后添加方括号:color[]。当 PHP 看到这种模式时,它会自动创建一个数组。URL 示例:
?color[]=red&color[]=green&color[]=blue\n在服务器端,$_GET 将包含:
array(1) {\n ["color"] => array(3) {\n [0] => string(3) "red"\n [1] => string(5) "green"\n [2] => string(4) "blue"\n }\n}\n现在是一个处理此问题的 PHP 代码示例:
\n<?php\n// URL: example.com?color[]=red&color[]=green&color[]=blue\nif (isset($_GET['color']) && is_array($_GET['color'])) {\n echo "选中的颜色:<br>";\n foreach ($_GET['color'] as $index => $color) {\n echo ($index + 1) . ". " . htmlspecialchars($color) . "<br>";\n }\n}\n?>\n浏览器中的结果:
\n选中的颜色:\n1. red\n2. green\n3. blue\n\n命名键:当顺序不重要时
\n有时需要传递一个关联数组(键 → 值)。为此,请使用带有指定键的 key[] 语法:
?filter[category]=books&filter[price]=100&filter[in_stock]=1\nPHP 会将其转换为:
\narray(1) {\n ["filter"] => array(3) {\n ["category"] => string(5) "books"\n ["price"] => string(3) "100"\n ["in_stock"] => string(1) "1"\n }\n}\n服务器端处理:
\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 // ... 其余条件\n}\n?>\n\n方法 #2:查询字符串中的 JSON(高级)
\n如果数组很复杂(多层嵌套),方括号语法会变得冗长。另一种方法是传递一个经过 URL 编码的 JSON 字符串。
\n在客户端(JavaScript)构建 URL:
\nconst data = {\n colors: ['red', 'green', 'blue'],\n sizes: ['S', 'M', 'L'],\n options: {\n gift_wrap: tr