PHP 入门 · 约 8 分钟

使用 PHP cURL 接入 AINN API

本教程先用命令行验证文本对话接口,适合 PHP、Nginx 和宝塔环境。使用 PHP 自带的 cURL 扩展即可发送请求,无需安装额外 SDK 或 Composer 包。

开始前准备

  • PHP 8.2 或更高版本,并启用 cURL 扩展
  • AINN API 账号有可用余额或已获得体验额度
  • 已创建 API 令牌,并确认支持 Chat Completions 的模型标识
1

章节 1

确认 PHP 版本与 cURL 扩展

宝塔可以同时安装多个 PHP 版本,终端中的 php 不一定与网站运行版本相同。以下命令以宝塔 PHP 8.4 为例;使用其他版本时替换路径中的 84。

宝塔终端
/www/server/php/84/bin/php -v
/www/server/php/84/bin/php --ri curl
如果未检测到 cURL,在宝塔对应 PHP 版本的扩展管理中启用,并再次检查。示例使用 CLI 运行,暂时不涉及 Nginx 或 PHP-FPM 配置。
2

章节 2

设置 API Key 环境变量

在当前终端设置 AINN_API_KEY,不要把真实密钥写入 PHP 文件。把下方占位符替换为自己的完整令牌,不要添加 Bearer 前缀。

macOS / Linux / 宝塔终端
export AINN_API_KEY="你的 API Key"
Windows PowerShell
$env:AINN_API_KEY="你的 API Key"
终端中 export 的变量只对当前会话及其子进程生效。普通 PHP 不会自动加载 .env;PHP-FPM 也不会自动继承 SSH 终端变量。接入网站时应使用项目自己的服务端密钥配置方式;Laravel 项目应在配置文件中读取 env,再通过 config 使用。
3

章节 3

保存并发送文本对话请求

将代码保存为 UTF-8 编码的 main.php,放在网站公开目录之外。把 your-model 替换为模型广场的准确标识;也可以使用接入配置助手生成自己的 PHP 示例。

main.php
<?php

try {
    $apiKey = getenv('AINN_API_KEY');
    if ($apiKey === false || trim($apiKey) === '') {
        throw new RuntimeException('请先设置 AINN_API_KEY 环境变量');
    }
    if (!function_exists('curl_init')) {
        throw new RuntimeException('请为当前 PHP 启用 cURL 扩展');
    }

    $payload = [
        'model' => 'your-model',
        'messages' => [['role' => 'user', 'content' => '用一句话介绍你自己']],
    ];
    $requestBody = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
    $curl = curl_init('https://api.ainn.cc/v1/chat/completions');
    if ($curl === false) {
        throw new RuntimeException('无法初始化 cURL');
    }

    try {
        curl_setopt_array($curl, [
            CURLOPT_POST => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_TIMEOUT => 60,
            CURLOPT_HTTPHEADER => [
                'Authorization: Bearer ' . $apiKey,
                'Content-Type: application/json',
            ],
            CURLOPT_POSTFIELDS => $requestBody,
        ]);
        $body = curl_exec($curl);
        if ($body === false) {
            throw new RuntimeException('网络请求失败:' . curl_error($curl));
        }
        $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    } finally {
        curl_close($curl);
    }

    if ($status < 200 || $status >= 300) {
        $errorData = json_decode($body, true);
        $message = $errorData['error']['message'] ?? '请查看使用日志并核对密钥、模型和余额';
        throw new RuntimeException('HTTP ' . $status . ':' . (is_string($message) ? $message : '接口请求失败'));
    }

    $response = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
    $reply = $response['choices'][0]['message']['content'] ?? null;
    if (!is_string($reply) || trim($reply) === '') {
        throw new RuntimeException('响应没有文本回复,请检查模型能力及响应结构');
    }
    echo $reply . PHP_EOL;
} catch (Throwable $exception) {
    fwrite(STDERR, $exception->getMessage() . PHP_EOL);
    exit(1);
}
4

章节 4

运行并核对使用日志

在 main.php 所在目录执行命令。普通环境可以使用 php main.php;宝塔 PHP 8.4 使用以下完整路径。收到回复后,到使用日志核对模型、时间和消耗。

宝塔终端
/www/server/php/84/bin/php main.php
这是命令行示例,错误通过 STDERR 输出。接入 Web 项目时应改为服务端日志与适当的 HTTP 错误响应,不要把完整上游错误或密钥直接显示给访客。
5

章节 5

排查 PHP 与接口错误

先确认执行脚本的 PHP 环境,再根据状态码和错误信息定位问题。排查时不要公开完整令牌。

  • 提示未设置 AINN_API_KEY:确认在运行脚本的同一终端设置了变量;.env 文件本身不会被此独立脚本自动读取
  • 提示 cURL 扩展不可用:检查执行脚本的 PHP 版本,并为该版本启用 cURL
  • 网络失败或超时:检查服务器 DNS、HTTPS 出站连接及模型响应速度;不要无限重试,超时不代表上游未处理或未计费
  • SSL 证书错误:检查系统时间和 CA 证书配置,保持 HTTPS 证书校验,不要关闭 CURLOPT_SSL_VERIFYPEER
  • HTTP 401:核对令牌;HTTP 404:检查 /v1/chat/completions 路径和模型协议;余额或模型错误:查看控制台与使用日志
  • JSON 解析失败或没有文本回复:确认返回格式;工具调用、拒绝回复、流式输出和其他协议需要单独处理

完成检查

  • PHP 命令行能正常打印模型回复
  • 真实令牌未写入 PHP 文件或公开目录
  • 使用日志中能核对本次调用及消耗