PHP 8.3 封装统一 AI 调用服务类,通过只读 DTO、联合类型、构造器属性提升等新特性实现高类型安全与低侵入扩展;定义 AiProvider 接口及工厂模式解耦模型,AiService 依赖注入 provider 并委托调用,支持命名参数与轻量中间件钩子。

在 PHP 8.3 中封装统一 AI 调用服务类,核心是抽象不同模型(如 OpenAI、Qwen、GLM、DeepSeek 等)的共性接口,利用新特性(如只读类、联合类型、命名参数、构造器属性提升)提升类型安全与可维护性。关键不在于支持多少模型,而在于让新增模型只需实现少量契约,不侵入原有调用逻辑。
定义标准化请求与响应结构
避免各 SDK 返回格式五花八门,统一收口输入输出:
- 请求用只读 DTO 类(PHP 8.3 支持
readonly class),含model: string、messages: array、temperature: float = 0.7、max_tokens: ?int等标准字段 - 响应封装为
AiResponse:含content: string、usage: array、raw: array|object(保留原始响应便于调试) - 错误统一抛出自定义异常
AiRequestException,含provider、status_code、error_message
用接口+工厂实现模型解耦
声明 AiProvider 接口,强制实现 call(array $payload): AiResponse 方法;每个厂商对应一个具体类(如 OpenAiProvider、QwenProvider),仅关注自身协议细节(鉴权头、Endpoint、JSON 结构映射)。
通过简单工厂或依赖注入容器按配置动态创建实例:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 配置项示例:
['default' => 'openai', 'providers' => ['openai' => [...], 'qwen' => [...]]] - 工厂根据
$config['default']或显式传入的provider名称返回对应实例 - PHP 8.3 的
match表达式可简洁替代长 if-else 分支
利用构造器属性提升简化客户端初始化
主服务类 AiService 不直接 new 各 provider,而是接收已实例化的 AiProvider 对象(依赖注入):
- 构造器使用属性提升:
public function __construct(private readonly AiProvider $provider) {} - 调用方法如
chat(string|Message ...$messages): AiResponse,内部将参数组装为标准 payload 后委托给$this->provider->call(...) - 支持命名参数(PHP 8.0+):
$service->chat(messages: [$msg], temperature: 0.2),语义清晰
添加轻量中间件支持可扩展性
不引入复杂中间件栈,但预留钩子应对通用需求:
- 前置处理:自动补全 system message、日志记录请求摘要、token 预估(基于
symfony/string的字节估算) - 后置处理:响应缓存(PSR-6)、敏感词过滤(正则或第三方库)、流式响应转 chunked 字符串
- 用闭包或简单策略接口实现,例如
afterCall(callable $handler)注册回调,保持低耦合
不复杂但容易忽略:务必为所有网络调用设置超时(stream_context_create(['http' => ['timeout' => 30]])),并重试逻辑(如幂等 GET 请求可重试,POST 建议配合 idempotency key)。PHP 8.3 的 try/catch 模式已足够清晰,无需额外封装 try-with-resources。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










