最近在做一个天气预报查询的小项目,用到了PHP处理GET请求。本来以为这东西简单得跟喝水一样,结果踩坑踩到怀疑人生。今天就把这些血泪史分享出来,顺便教你怎么优雅地处理GET请求。
先来个最基础的例子,假设我们要获取城市名称然后查询天气:
$city = $_GET['city'];
echo "您查询的城市是:" . $city;
看起来很简单对?但这里至少有3个坑等着你:
1. 用户可能根本不传city参数
2. 传过来的可能是
3. 中文城市名可能会乱码
先说第一个问题。当你兴冲冲地访问weather.php时,啪,直接给你个Undefined index警告。解决方法很简单:
$city = $_GET['city'] ?? '北京';
这个??是PHP7的null合并运算符,相当于isset($_GET['city']) ? $_GET['city'] : '北京'。不过你要是还在用PHP5.6...兄弟,该升级了。
第二个安全问题更刺激。有个用户传了个city=%3Cscript%3Ealert(1)%3C/script%3E,然后你的页面就变成了XSS重灾区。解决方法:
$city = htmlspecialchars($_GET['city'] ?? '北京', ENT_QUOTES);
htmlspecialchars会把 <变成<,> 变成>,这样脚本就执行不了了。ENT_QUOTES参数表示连单引号也转义。
第三个中文乱码问题,我见过最骚的操作是有人这样解决:
header('Content-Type:text/html;charset=gbk');

$city = iconv('utf-8', 'gbk', $_GET['city']);
结果用户传的是utf-8编码的参数,他非要转成gbk,最后显示出来全是问号。正确的做法是统一使用utf-8:
GET参数处理还有个常见需求就是分页。比如:
$page = intval($_GET['page'] ?? 1);
if($page < 1) $page = 1;
这里用intval确保page是整数,避免SQL注入。不过更严谨的做法是用filter_var:
$page = filter_var($_GET['page'] ?? 1, FILTER_VALIDATE_INT, [
'options' => [
'default' => 1,
'min_range' => 1
]
]);
说到URL构造,新手常犯的错误是这样的:
如果$keyword包含&或者?就会破坏URL结构。正确的做法是:

urlencode会把特殊字符编码成%XX的形式。不过注意,不要在已经编码过的字符串上再次编码,否则会出现双重编码的问题。
GET请求的长度限制是个坑。虽然理论上URL可以很长,但不同浏览器和服务器有不同的限制。我曾经遇到一个案例,用户要传一大串ID过来查询:
?id=1,2,3,4,5,...(总共500个ID)
结果在IE上直接报414错误。解决方案要么改用POST,要么分批请求。
处理数组参数也是个技术活。比如多选筛选:
?category[]=1&category[]=2
获取时要这样:
$categories = $_GET['category'] ?? [];
if(!is_array($categories)) {
$categories = [$categories];
}
因为用户可能手贱直接传?category=1,这样$_GET['category']就不是数组了。
再说说URL路由。很多框架都把PATH_INFO转成GET参数,比如:
/user/profile/123
实际上会被转换成:
处理这种请求时要注意服务器配置。Apache需要开启AcceptPathInfo,Nginx要配置try_files。

最后分享一个真实案例。我们有个API接口要传时间范围:
?start=2020-01-01&end=2020-01-31
结果用户传了个:
?start=昨天&end=明天
处理日期参数一定要验证:
$start = strtotime($_GET['start'] ?? 'today');
if($start === false) $start = strtotime('today');
$start = date('Y-m-d', $start);
总结一下GET请求的最佳实践:
1. 永远要检查参数是否存在
2. 对用户输入进行过滤和转义
3. 处理特殊类型(日期、数字等)时要验证
4. 注意URL编码和长度限制
5. 数组参数要特殊处理
看起来简单的GET请求,要写好还真得掉几层皮。不过等你把这些坑都踩过一遍,就会发现...还是POST好用。开个玩笑,GET在适合的场景下还是很香的,比如缓存、书签、SEO这些方面都有优势。
962

被折叠的 条评论
为什么被折叠?



