PHP超全局变量值恒为字符串,须依来源选择filter_var等安全转换方式,JSON请求需手动解析,转换后仍需业务校验与参数绑定。

PHP 接收的参数类型不对,不是靠“强制转换”就能一劳永逸解决的——关键得先确认来源、再决定转换策略,否则可能掩盖逻辑错误或引发安全问题。
$_GET、$_POST 里的值永远是字符串
无论前端传的是数字、布尔还是空数组,$_GET['id'] 和 $_POST['limit'] 拿到的都是字符串。比如传了 id=123,实际值是 "123",不是整数 123;传了 active=false,拿到的是字符串 "false",不是布尔 false。
常见错误现象:
- 用
===判断$_GET['page'] === 1永远为false -
if ($_POST['enabled'])对"0"或"false"误判为真(因为非空字符串在 PHP 中为真) - 传入数据库查询时,
WHERE id = ?绑定字符串"123"虽然能查出结果,但若字段是INT,MySQL 可能无法走索引(尤其在严格模式下)
用 (int)、(bool)、filter_var() 还是 settype()?
直接类型转换符号(如 (int))最常用,但有陷阱;filter_var() 更安全,适合验证+转换一体;settype() 会修改原变量,一般不推荐用于超全局数组。
立即学习“PHP免费学习笔记(深入)”;
实操建议:
- 转整数:优先用
filter_var($_GET['id'], FILTER_VALIDATE_INT),失败返回false,可配合默认值和范围检查 - 转布尔:别用
(bool)——"0"、"false"、"off"都会变成true;改用filter_var($_POST['publish'], FILTER_VALIDATE_BOOLEAN),它识别"1"/"true"/"on"为true,"0"/"false"/"off"/"no"为false - 转浮点:
filter_var($_GET['price'], FILTER_VALIDATE_FLOAT)比(float)更可靠,能拒绝"12.34abc"这类脏数据 - 避免直接
(int)"12.9"→ 得到12(截断),而intval("12.9", 10)行为相同,但语义更清晰
JSON 请求体(application/json)要先 json_decode()
当前端用 fetch() 或 axios 发送 JSON 数据时,$_POST 是空的——PHP 不自动解析 JSON 请求体。必须手动读取原始输入并解码。
实操步骤:
- 检查
$_SERVER['CONTENT_TYPE']是否含"application/json" - 用
$raw = file_get_contents('php://input')获取原始 body - 用
$data = json_decode($raw, true)解析成关联数组 - 此时
$data['count']才可能是整数或布尔,而非字符串
示例:
$raw = file_get_contents('php://input');
if (!empty($raw)) {
$json = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
exit('Invalid JSON');
}
$id = filter_var($json['id'] ?? null, FILTER_VALIDATE_INT);
}
别跳过验证,转换 ≠ 安全
类型转换只是第一步,不能替代业务校验。比如把 $_GET['page'] 强转成 int,不代表它就合法——还可能为负数、超出分页范围、或被用于 SQL 注入(如果拼接进查询)。
容易被忽略的地方:
-
filter_var()默认不处理null或缺失键,记得用??提供默认或显式判断键是否存在 - 数据库写入前,仍需用 PDO 参数绑定或
filter_var()二次确认,不能只信“我已经转过了” - API 返回给前端的数据,也要注意类型一致性——PHP 数组里
0和"0"在 JSON 中序列化结果不同(前者是数字,后者是字符串)











