declare(strict_types=1)仅严格校验当前文件中函数调用的参数与返回值类型,禁止隐式转换;不影响变量赋值、表达式运算、跨文件引入及类属性等,且必须置于文件首行(PHP标签后无空行或注释)。

strict_types=1 不改变 PHP 的弱类型本质,只收紧函数调用时的参数和返回值校验边界。 它不是“让 PHP 变成强类型语言”,而是给函数接口加了一道运行时契约检查——变量本身仍可随时被赋不同类型的值,表达式计算也照常隐式转换。
strict_types=1 只影响哪些地方?
它只在函数调用入口处插一道检查,其余一切照旧:
-
declare(strict_types=1)必须写在文件最顶部(<?php后紧接,前面不能有空行、注释或输出) - 仅对当前文件中定义的函数(含
function和方法)的入参类型声明和返回值类型声明生效 - 不影响变量赋值:
$x = "123"; $x = 42;合法,不报错 - 不影响表达式运算:
1 + "2.5"仍得3.5,不触发检查 - 不传播到
include/require的文件,也不影响 trait 或父类中未显式声明 strict_types 的方法
为什么传 int 却收到 string 还是 TypeError?
因为严格模式下,PHP 不再尝试把 "123" 转成 int 去凑合函数签名。它只看实际传入值的 ZVAL type 字段是否为 IS_LONG:
function foo(int $x): void { }-
foo(123);✅ ——IS_LONG -
foo("123");❌ ——IS_STRING,抛出TypeError: Argument #1 must be of type int, string given -
foo(123.0);❌ ——IS_DOUBLE,即使数值相等也不行
strict_types=1 和类型声明(如 int $x)是两回事
类型声明(scalar/object/array 等)早在 PHP 7.0 就支持了,但默认是弱检查;strict_types=1 是开启“不妥协”的校验开关:
立即学习“PHP免费学习笔记(深入)”;
- 没写
declare(strict_types=1):函数仍可声明int $x,但"42"会被静默转成42 - 写了
declare(strict_types=1):同个int $x就拒绝任何非int类型,哪怕只是多了一个小数点 - 注意:
array $arr、object $obj、callable $cb等复合类型,在 strict_types=1 下同样要求精确匹配,不接受null或字符串伪装
最容易被忽略的一点:strict_types 是文件级开关,不是项目级配置。你无法靠 composer autoload 或 php.ini 统一打开它——每个需要严格校验的文件都得自己写一行 declare(strict_types=1),漏掉一个,那个文件的函数调用就退回弱类型逻辑。



















