本文目录导读:

PHP 的返回类型声明(Return Type Declarations)是 PHP 7.0 引入、并在后续版本不断增强的核心特性,它讲究的是契约明确、类型安全与性能优化。
以下是 PHP 返回类型在定义、语法和设计上的“讲究”:
核心语法:哪里写?怎么写?
在函数或方法的参数括号后、花括号前,加上冒号和类型。
function add(int $a, int $b): int {
return $a + $b;
}
可用的返回类型(讲究点之一:类型清单)
- 标量类型(PHP 7.0+):
int、float、string、bool - 复合类型:
array(PHP 7.0+)callable(PHP 7.0+,不推荐用于返回,因为不好检查)iterable(PHP 7.1+,接受数组和 Traversable 对象)object(PHP 7.2+,任何对象)
- 特殊类型:
void(PHP 7.1+):必须无return语句,或return;不带值,否则报错。mixed(PHP 8.0+):任意类型。never(PHP 8.1+):永不返回(要么抛异常,要么exit()),并且不能有return语句。null(PHP 8.2+,作为独立类型或联合类型中的一部分)。false/true(PHP 8.2+,常用于返回布尔假或真,替代bool以更精确)。
- 类/接口类型:可以返回一个类名或接口名。
- 联合类型(PHP 8.0+):用 隔开,如
int|string。 - 交集类型(PHP 8.1+):用
&隔开,如Countable&Iterator,要求返回对象同时实现这些接口。 static(后期静态绑定)(PHP 8.0+):返回调用类本身的实例,解决self不够灵活的问题。self/parent:返回当前类或父类的实例。
返回类型的“讲究”之处(重点)
强类型与弱类型的权衡(Coercive vs Strict)
- 默认(弱类型):如果不写
declare(strict_types=1);,PHP 会尝试自动转换返回值,返回int但写了"123abc",会转换成123(非严格模式下)。 - 严格模式:文件顶部写
declare(strict_types=1);后,返回类型不匹配会直接抛TypeError,绝不自动转换。 - 讲究:在现代 PHP 项目中,必须启用严格模式,以消除隐式转换带来的 Bug。
void 与 never 的区别(虽然都“无返回”,但不同)
void:函数正常结束,只是不返回数据,可以提前return;。never:函数永远不会结束(抛异常或退出进程)。不能包含return;。- 讲究:如果写
void却执行了exit(),虽然合法,但语义上应写never。
协变与逆变(继承时的类型规则)
- 返回类型(协变):子类覆盖父类方法时,返回类型必须相同或更具体(收窄)。
- 父类返回
Animal,子类可以返回Dog(因为 Dog 是 Animal 的子类)。不能更宽泛(返回object)。
- 父类返回
- 参数类型(逆变):参数类型必须相同或更宽泛(放宽),这是 PHP 7.4+ 新增的完整支持。
- 讲究:这是接口设计的关键,保证
Liskov 替换原则。
static 返回类型解决了“链式调用”的痛点
- 以前用
self返回类型,如果子类调用父类方法并链式调用子类方法,会报错。 static返回类型允许子类继承时,返回类型自动变成子类本身。- 讲究:做 Fluent 接口(构建器模式)时,强烈推荐
static而非self。
实际案例展示“讲究”的意义
案例 1:防止马虎 Bug(严格模式)
declare(strict_types=1);
function divide(float $a, float $b): float {
return $a / $b; // $b 为 0,返回 INF,不报错,若返回类型是 int,则抛 TypeError。
}
案例 2:static 返回类型的优雅之处
class Base {
public function copy(): static {
return clone $this;
}
}
class Child extends Base {
public function extra(): void {}
}
$c = new Child();
$c->copy()->extra(); // 如果没有 static,这里会报错,因为 copy() 返回 Base 类型。
案例 3:mixed 是最后的救赎(避免过度设计)
// 反模式:过度限制返回类型导致代码脆弱
public function getValue(): int { return $this->value; }
// 合理模式:明确会返回多种类型
public function getValue(): mixed { return $this->value; }
最佳实践总结(讲究清单)
- 始终开启
declare(strict_types=1);——将类型检查从“尽力转换”变为“严格校验”。 - 优先声明具体类型:
Dog优于Animal,int优于mixed,除非确有必要。 - 区分
void(正常结束)和never(异常/退出),表达明确的函数意图。 - 使用
static而非self作为返回类型,以支持继承后的链式调用。 - 注意联合类型顺序:
int|string会按顺序尝试匹配,但实际匹配不依赖顺序;不过写代码时要考虑可读性。 - 不要为了“漂亮”而滥用:如果返回类型无法确定,用
mixed或者拆分成多个专用方法,避免一个方法返回多个不相关的复杂结构。
一句话总结:PHP 返回类型不只是“写个类型”,而是一套关于代码契约、继承规则和运行效率的设计哲学,掌握这些“讲究”,能让你的代码从“能跑”变成“健壮可维护”。