PHP 签名 SDK 接入指南

功能说明

PHP 签名 SDK 用于为美图开放平台 API 请求生成签名。SDK 会生成 X-Sdk-DateAuthorization 请求头,并返回已配置的 cURL handle。调用方使用 curl_exec() 发送请求并处理响应。

环境要求

  • PHP 7.0 或更高版本
  • PHP cURL 扩展
  • 可通过 HTTPS 访问 openapi.meitu.com

检查 cURL 扩展:

php -m | grep curl

下载与引入

下载 AIGCP-API-php-sdk-1.0.9.zip,解压后将 signer.php 复制到项目中。

AIGCP-API-php-sdk-1.0.9/
├── index.php
└── signer.php

在业务代码中引入 SDK:

require_once __DIR__ . '/signer.php';

接口说明

创建签名器并生成请求:

$signer = new Signer($accessKey, $secretKey);
$curl = $signer->sign($url, $method, $headers, $body);

Signer::sign() 参数如下:

参数说明
$url完整请求 URL,包括路径和查询参数。
$method大写 HTTP 方法,例如 GETPOST
$headers请求头关联数组。必须设置与 URL 一致的 Host;JSON 请求设置 Content-Type: application/json
$body最终发送的字符串。无请求体时传空字符串 ''

sign() 返回 cURL handle,不会发送请求。PHP 8 中返回 CurlHandle,PHP 7 中返回 cURL resource。调用 curl_exec($curl) 发送请求,使用完成后调用 curl_close($curl)

POST 完整调用示例

下面的示例调用同步推送接口 https://openapi.meitu.com/api/v1/sdk/sync/push。将 tasktask_typeinit_imagesparams 替换为目标能力 API 文档要求的值。

<?php
declare(strict_types=1);

require_once __DIR__ . '/signer.php';

$accessKey = getenv('AIGCP_ACCESS_KEY');
$secretKey = getenv('AIGCP_SECRET_KEY');
if (!is_string($accessKey) || $accessKey === '' ||
    !is_string($secretKey) || $secretKey === '') {
    throw new RuntimeException('AIGCP_ACCESS_KEY and AIGCP_SECRET_KEY are required');
}

$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$params = json_encode(
    ['replace_with_target_api_parameter' => 'example value'],
    JSON_UNESCAPED_SLASHES
);
if ($params === false) {
    throw new RuntimeException('params JSON encoding failed: ' . json_last_error_msg());
}

$body = json_encode(
    [
        'task' => 'replace-with-task-from-target-api-documentation',
        'task_type' => 'replace-with-task-type-from-target-api-documentation',
        'init_images' => ['https://example.com/input.jpg'],
        'params' => $params,
        'sync_timeout' => 30,
    ],
    JSON_UNESCAPED_SLASHES
);
if ($body === false) {
    throw new RuntimeException('request JSON encoding failed: ' . json_last_error_msg());
}

$headers = [
    'Content-Type' => 'application/json',
    HeaderHost => 'openapi.meitu.com',
];

$signer = new Signer($accessKey, $secretKey);
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt_array($curl, [
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 60,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_HEADER => false,
]);

$response = curl_exec($curl);
if ($response === false) {
    $errorNumber = curl_errno($curl);
    $errorMessage = curl_error($curl);
    curl_close($curl);
    throw new RuntimeException("cURL error {$errorNumber}: {$errorMessage}");
}

$statusCode = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

if ($statusCode < 200 || $statusCode >= 300) {
    throw new RuntimeException("HTTP {$statusCode}: {$response}");
}

echo $response . PHP_EOL;

运行示例:

export AIGCP_ACCESS_KEY='<your-access-key>'
export AIGCP_SECRET_KEY='<your-secret-key>'
php index.php

请求体顶层固定包含 tasktask_typeinit_imagesparamssync_timeoutparams 必须是 JSON 字符串。示例中的图片、业务参数和 sync_timeout: 30 仅作演示,具体要求以目标能力 API 文档为准。

GET 调用示例

GET 请求应先生成包含全部查询参数的最终 URL,再调用 sign()。下面的示例从 AIGCP_GET_API_URL 读取对应 GET 接口文档提供的完整 HTTPS URL,并复用上一节创建的 $signer

$getUrl = getenv('AIGCP_GET_API_URL');
if (!is_string($getUrl) || $getUrl === '') {
    throw new RuntimeException('AIGCP_GET_API_URL is required');
}

$getUrlParts = parse_url($getUrl);
if (!is_array($getUrlParts) || ($getUrlParts['scheme'] ?? '') !== 'https' || empty($getUrlParts['host'])) {
    throw new RuntimeException('AIGCP_GET_API_URL must be a valid HTTPS URL');
}

$getHost = $getUrlParts['host'];
if (isset($getUrlParts['port']) && $getUrlParts['port'] !== 443) {
    $getHost .= ':' . $getUrlParts['port'];
}

$getHeaders = [
    HeaderHost => $getHost,
];
$getCurl = $signer->sign($getUrl, 'GET', $getHeaders, '');
curl_setopt_array($getCurl, [
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 60,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_HEADER => false,
]);

$getResponse = curl_exec($getCurl);
if ($getResponse === false) {
    $errorNumber = curl_errno($getCurl);
    $errorMessage = curl_error($getCurl);
    curl_close($getCurl);
    throw new RuntimeException("cURL error {$errorNumber}: {$errorMessage}");
}

$getStatusCode = (int) curl_getinfo($getCurl, CURLINFO_HTTP_CODE);
curl_close($getCurl);

if ($getStatusCode < 200 || $getStatusCode >= 300) {
    throw new RuntimeException("HTTP {$getStatusCode}: {$getResponse}");
}

echo $getResponse . PHP_EOL;

注意事项

  • URL、HTTP 方法、请求头和 body 必须在签名前确定,签名后不能修改;POST 示例把同一个 $body 同时用于签名和发送。
  • Host 必须与 URL 主机一致,HTTP 方法必须使用大写,GET 查询参数必须在签名前加入 URL。
  • 保持服务器时间准确,并始终使用 HTTPS。
  • SK 仅保存在服务端。

常见错误

错误处理方法
Class "Signer" not found检查 signer.php 路径和 require_once
Call to undefined function curl_init()安装并启用 PHP cURL 扩展。
curl_exec() 返回 false查看 curl_errno()curl_error(),检查网络、DNS、证书和超时。
HTTP 401 或签名校验失败检查 AK/SK、服务器时间、HTTP 方法、URL、Host、请求头和 body 是否与签名时一致。
HTTP 4xx按目标能力 API 文档检查 tasktask_type、图片、params 和其他业务约束。
响应中包含 HTTP 头SDK 默认启用 CURLOPT_HEADER;按示例将其设置为 false