PHP Signature SDK Integration Guide
Overview
The PHP Signature SDK signs Meitu Open Platform API requests. It generates the X-Sdk-Date and Authorization headers and returns a configured cURL handle. The caller sends the request with curl_exec() and processes the response.
Requirements
- PHP
7.0or later - PHP cURL extension
- HTTPS access to
openapi.meitu.com
Check the cURL extension:
php -m | grep curlDownload and import
Download AIGCP-API-php-sdk-1.0.9.zip, extract it, and copy signer.php into your project.
AIGCP-API-php-sdk-1.0.9/
├── index.php
└── signer.phpImport the SDK in your application code:
require_once __DIR__ . '/signer.php';API
Create a signer and prepare a request:
$signer = new Signer($accessKey, $secretKey);
$curl = $signer->sign($url, $method, $headers, $body);Signer::sign() accepts these parameters:
| Parameter | Description |
|---|---|
$url | Complete request URL, including the path and query parameters. |
$method | Uppercase HTTP method such as GET or POST. |
$headers | Associative array of request headers. Set a Host that matches the URL; JSON requests also use Content-Type: application/json. |
$body | Final string to send. Pass an empty string '' when there is no request body. |
sign() returns a cURL handle and does not send the request. It returns a CurlHandle on PHP 8 and a cURL resource on PHP 7. Call curl_exec($curl) to send it and curl_close($curl) when finished.
Complete POST example
This example calls the synchronous push endpoint at https://openapi.meitu.com/api/v1/sdk/sync/push. Replace task, task_type, init_images, and params with values required by the target capability API documentation.
<?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;Run the example:
export AIGCP_ACCESS_KEY='<your-access-key>'
export AIGCP_SECRET_KEY='<your-secret-key>'
php index.phpThe request body always has task, task_type, init_images, params, and sync_timeout as its top-level fields. params must be a JSON string. The image, business parameters, and sync_timeout: 30 in this example are illustrative; follow the target capability API documentation for their actual requirements.
GET example
For GET, build the final URL with all query parameters before calling sign(). This example reads the complete HTTPS URL from the target GET API documentation through AIGCP_GET_API_URL and reuses the $signer created in the previous section.
$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;Notes
- Finalize the URL, HTTP method, headers, and body before signing and do not change them afterward. The POST example uses the same
$bodyfor signing and transmission. Hostmust match the URL host, HTTP methods must be uppercase, and GET query parameters must be included in the URL before signing.- Keep the server clock accurate and always use HTTPS.
- Store the SK only on the server.
Common errors
| Error | Resolution |
|---|---|
Class "Signer" not found | Check the signer.php path and the require_once statement. |
Call to undefined function curl_init() | Install and enable the PHP cURL extension. |
curl_exec() returns false | Inspect curl_errno() and curl_error(), then check the network, DNS, certificate, and timeouts. |
| HTTP 401 or signature verification fails | Check the AK/SK, server time, HTTP method, URL, Host, headers, and body against the signed request. |
| HTTP 4xx | Check task, task_type, the image, params, and other business requirements in the target capability API documentation. |
| HTTP headers appear in the response | The SDK enables CURLOPT_HEADER by default; set it to false as shown in the examples. |