__construct() 是对象创建时唯一自动调用的初始化方法,必须严格命名、避免业务逻辑、注意继承调用与参数匹配,并优先用工厂模式解耦复杂初始化。

__construct() 不是“学怎么写”的问题,而是“怎么用对、怎么避坑”的问题。它只在 new 时触发一次,不能手动调用,也不该塞业务逻辑——这是绝大多数初学者卡住的起点。
构造函数名写错就静默失效
PHP 严格要求构造函数必须叫 __construct(两个下划线 + 小写 construct),大小写敏感,拼错一个字母都不行。
-
__constructor、Construct、myConstruct:全部无效,不报错,但初始化代码完全不执行 - 类里写了属性赋值或
echo,new后却没反应?先查函数名 - PHP 8+ 已彻底废弃“与类同名”的旧式构造函数,命名空间中哪怕写对了类名也不会被识别
子类重写构造函数必须手动调用父类
子类定义了 __construct(),父类的构造逻辑就自动断掉,不会隐式继承。
- 漏写
parent::__construct()→ 父类的资源连接、参数校验、属性初始化全跳过 - 调用位置不重要,但参数必须匹配父类签名;如果父类需要
$host,子类就得传过去 - 父类构造函数是
private?那子类根本无法调用,设计上已禁止继承
参数类型和顺序不能靠“猜”
new 传参完全由 __construct() 的形参决定,PHP 不支持命名参数(new User(name: "A") 是非法的),也不支持跳过中间参数。
- 必填参数在前、默认参数在后,否则直接
Parse error -
declare(strict_types=1)开启后,"123"传给int $id会抛TypeError,不开则可能静默转成123 - PHP 8.0+ 支持构造函数属性提升,但仅限于 public/protected/private 修饰的参数:
public function __construct(public string $name) { },此时无需手动写$this->name = $name
构造函数里别做耗时或不可控的事
对象创建应是轻量、可预测的。把远程请求、大文件读取、复杂校验塞进 __construct(),会让 new 变成黑盒,也难测试、难 mock。
立即学习“PHP免费学习笔记(深入)”;
- 数据库连接、配置加载、API 初始化 → 改用工厂方法(如
User::fromConfig($cfg))或显式init() - 构造函数抛异常 → 对象不会被创建,但调用方必须处理,否则脚本中断
- 反序列化对象(
unserialize())不会再次触发__construct(),依赖构造函数初始化的状态会丢失
new 承担不该承担的责任。



















