PHP 8.1 中对象适配器是首选方案,因其通过组合+接口规避继承问题、便于测试与注入;需严格定义目标接口类型、避免私有方法访问、统一错误处理并遵守PSR-4自动加载规范。

PHP 8.1 中对象适配器是首选方案
PHP 8.1 已完全弃用 mysql_* 系列函数,且严格类型检查更激进,类适配器(继承方式)容易触发 TypeError 或违反 LSP 原则。对象适配器通过组合 + 接口实现,天然规避了继承链断裂、构造器签名不一致等问题,也便于单元测试和依赖注入。
关键点在于:目标接口必须定义清晰,被适配类(Adaptee)不修改,适配器只负责“翻译”调用。
- 始终用
implements TargetInterface而非extends Adaptee - 适配器构造器接收
Adaptee实例,类型声明写明具体类或接口(如private Adaptee $adaptee) - PHP 8.1 的联合类型(
string|int)和mixed可用于处理 Adaptee 返回值不确定的场景 - 避免在适配器中重写 Adaptee 的私有方法——它不可见,强行访问会报
Fatal error: Cannot access private property
目标接口设计要兼顾 PHP 8.1 的类型安全
如果目标接口(TargetInterface)本身没加类型声明,适配器再严谨也没法阻止客户端传错参数。PHP 8.1 下必须显式标注参数和返回类型,否则 IDE 和静态分析工具(如 PHPStan)会失去约束力。
例如,一个数据库操作适配目标接口应这样写:
立即学习“PHP免费学习笔记(深入)”;
interface DatabaseClient
{
public function connect(string $host, string $user, string $pass, string $db): bool;
public function query(string $sql): array|false;
public function close(): void;
}
-
array|false是 PHP 8.0+ 支持的联合类型,比mixed更精确,也比旧版resource|array|bool更安全 - 不要用
void声明可能抛异常的方法——PHP 不强制检查,但团队协作中容易误判 - 若 Adaptee 方法返回
null(如某些 SDK 的失败回调),适配器内需显式转为false或抛RuntimeException,保持目标接口契约
适配第三方 SDK 时注意错误处理机制差异
PHP 8.1 默认开启 throw_on_error(部分扩展),而很多老 SDK(如早期 AWS SDK v2)仍靠返回 false + getError() 判断失败。直接适配会导致逻辑断裂。
- 适配器中不要简单透传
getError(),而应统一转为RuntimeException或自定义异常(如DatabaseConnectionException) - 若 SDK 使用
@抑制错误,PHP 8.1 会忽略但日志里仍记 warning——适配器应在catch (Error $e)后重新 throw,确保异常流可控 - 对返回
stdClass或ArrayObject的 SDK,适配器应封装为数组或 DTO 对象,避免客户端直操作原始结构(易受版本升级破坏)
Composer 自动加载与命名空间陷阱
PHP 8.1 强制 PSR-4,若适配器类文件路径与命名空间不严格匹配,Class not found 错误不会提示具体缺失路径,只会报 Uncaught Error: Class "XYZ" not found。
- 确保
composer.json的autoload段落正确映射适配器所在目录,例如:"autoload": { "psr-4": { "App\Adapter\": "src/Adapter/" } } - 适配器类名必须与文件名完全一致(含大小写),PHP 8.1 在 Linux 环境下区分大小写,本地开发用 Windows 可能侥幸通过,CI 环节必挂
- 不要在适配器中
require_once 'legacy/class.php'—— 违反自动加载原则,且无法被 Composer 优化 autoload classmap
最易被忽略的是:适配器内部若引用了已被废弃的全局函数(如 mysql_real_escape_string),PHP 8.1 会直接 fatal,连异常都捕获不到。务必用 function_exists() 包裹或提前用 polyfill 替换。



















