PHP警告:strtolower()参数应为字符串却传入数组的解决问询
问题解决思路与优化方案
触发警告的原因
你猜的没错,这个警告是因为有人构造了数组型查询参数,比如通过?foo[]=malicious这种方式提交请求,此时$_GET['foo']会被PHP解析成数组,直接传给strtolower()就会抛出参数类型不匹配的警告。
最优处理方案
直接拒绝数组类型的参数值是合理的——正常业务场景下,你的白名单参数应该都是单值字符串/数字/布尔,数组型参数本身就属于异常请求,直接标记为拒绝既能解决警告问题,也能提升安全性。
修改后的代码示例
$rejectqstr = "N"; foreach ($_GET as $key => $value) { // 第一步:检查参数值类型,数组直接标记拒绝并跳过后续检查 if (is_array($value)) { $rejectqstr = "Y"; continue; } // 第二步:检查参数键是否在白名单内 if (!in_array($key, $cmsnumparams) && !in_array($key, $cmsstrparams) && !in_array($key, $cmsboolparams)) { $rejectqstr = "Y"; } // 第三步:转小写后检查黑名单词汇,命中即标记并终止当前循环 $lowerValue = strtolower($value); foreach ($cmsblklstparams as $blklist) { if (strpos($lowerValue, $blklist) !== false) { $rejectqstr = "Y"; break; } } }
额外优化建议
- 按白名单类型做严格校验:既然分了数字、字符串、布尔三种白名单参数,可在通过键检查后对值做类型校验——比如数字参数用
is_numeric()验证,布尔参数检查是否为true/false或1/0,进一步缩小异常请求范围。 - 提前终止全量检查:如果已经标记
$rejectqstr = "Y",可以直接跳出整个$_GET循环,不用再处理后续参数,节省性能。 - 用
filter_input替代直接访问$_GET:比如filter_input(INPUT_GET, $key, FILTER_SANITIZE_STRING),能自动过滤非法字符,同时默认会把数组型参数转为空字符串,从源头上避免类型问题。
内容的提问来源于stack exchange,提问作者scim1971
相关产品推荐
相关产品推荐

