PHP 7.0+ 默认强制模式允许 int 参数静默转换字符串(如 '42'→42),而 PHP 5.x 不支持标量类型声明,写 int $x 直接报 Parse error;strict_types=1 仅对当前文件用户函数生效,不作用于内置函数或引入文件。

PHP 7.0+ 默认开启强制类型转换(coercive mode),int 和 string 参数传入时会静默转类型;PHP 5.x 完全不支持标量类型声明,写 function foo(int $x) 直接报语法错误。
PHP 5.x 中根本不能写 int 或 string 类型声明
PHP 5.6 及更早版本解析器不认识 int、string 这类参数类型标注,遇到 function sum(int $a, int $b) 会直接抛出 Parse error: syntax error, unexpected 'int'。你只能靠文档注释 + 手动校验:
- 用
is_int()/is_string()判断后 throw Exception - 用
filter_var($x, FILTER_VALIDATE_INT)做更严格的整数校验 - 别依赖 IDE 的类型提示——它可能“以为”有类型,但运行时根本没约束
PHP 7.0–7.3 默认是强制模式(coercive),int 参数能接受字符串
比如 function inc(int $n) { return $n + 1; },调用 inc('42') 不报错,PHP 自动把 '42' 转成整数 42;但 inc('abc') 会转成 0,结果是 1——这容易埋逻辑 bug。
- 数字开头的字符串(如
'42px')会被截断为42 - 纯非数字字符串(如
'hello')转成0,且不警告 - 空字符串
''也转成0,不是 null 或 false - 想禁用这种隐式转换?必须在文件顶部加
declare(strict_types=1);
PHP 8.0+ 对 null 更敏感,尤其在内置函数里
像 strlen(null) 在 PHP 7.x 强制模式下返回 0(隐式转空字符串),但 PHP 8.0+ 默认就抛 TypeError;PHP 8.1 更进一步:向声明为 string 的参数传 null,即使用户自定义函数也会触发 Deprecated: Passing null to parameter 警告。
立即学习“PHP免费学习笔记(深入)”;
- 不要假设
$_GET['id'] ?? 0后就能安全喂给function find(int $id)——如果$_GET['id']是空字符串或'null',仍可能被转成0导致查错记录 - 用
filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)替代简单(int)强转,它对非整数值返回false而非0 - 升级到 PHP 8.x 后,所有未显式声明
?string或?int的参数,null都是非法输入
严格模式不是全局开关,而是按文件生效
declare(strict_types=1) 只影响当前文件内定义的函数,不影响 include 进来的其他文件,也不改变内置函数行为(比如 array_sum() 永远按自身规则处理类型)。
- 如果你在一个文件里写了
declare(strict_types=1),但调用的是另一个没声明的文件里的函数,那个函数仍走强制模式 -
strlen('')在严格模式文件里依然返回0,因为strlen是内部函数,其行为由 PHP 版本决定,不受 strict_types 控制 - 跨文件协作时,建议统一项目级规范:要么全开 strict_types,要么全关,并在 CI 中用
php -l扫描遗漏
最易忽略的一点:类型声明的“边界感”只存在于函数签名层,一旦进入函数体,变量就只是普通 PHP 变量——int $x 并不阻止你在函数里给它赋值 $x = [],也不会自动做运行时类型检查。真要保类型,得靠静态分析工具(如 PHPStan)或测试覆盖。



















