filter_var闭包中in_array函数的异常行为原因咨询
为什么自定义FILTER_CALLBACK验证函数的严格类型匹配结果不符合预期?
你的问题核心是filter_var使用FILTER_CALLBACK时会自动转换输入值为字符串类型,导致闭包接收到的不是你传入的原始值,进而让严格模式的in_array验证结果不符合预期。
具体原因
当使用FILTER_CALLBACK时,filter_var会强制将待验证的标量值(整数、浮点数、布尔值等)转换为字符串,仅NULL和资源类型除外。比如:
- 你调用
filter_var(6, FILTER_CALLBACK, ...)时,闭包实际接收到的$value是字符串'6',而非原始的整数6。
对应你的测试用例:
- 第三个测试:传入整数6,闭包拿到
'6',和允许值'6'严格匹配,返回true——但你预期整数6和字符串'6'不匹配,所以觉得结果错误。 - 第四个测试:传入整数6,闭包拿到
'6',和允许值整数6严格不匹配,返回false——但你预期整数6和整数6匹配,所以结果错误。
解决方案
方案1:直接调用验证函数(推荐,保留严格类型匹配)
绕过filter_var的类型转换,直接调用你的闭包验证函数:
var_dump( is_one_of('6')(6) ); // bool(false) 符合预期 var_dump( is_one_of(6)(6) ); // bool(true) 符合预期
方案2:修改验证函数放弃严格类型匹配(仅当你接受松散匹配时使用)
如果一定要使用FILTER_CALLBACK,可以去掉in_array的第三个严格匹配参数:
function is_one_of() { $allowed_values = func_get_args(); return function($value) use ($allowed_values) { return in_array($value, $allowed_values); // 移除严格匹配 }; }
但这会允许松散类型匹配(比如整数6和字符串'6'被视为相等),可能不符合你的原始需求。
内容的提问来源于stack exchange,提问作者Fravadona
相关产品推荐
相关产品推荐

