本文目录导读:

在PHP中,API任务结果的回调通常有几种方式,具体取决于你的应用场景,以下是常见的情况:
HTTP异步回调(Webhook)
这是最常用的方式,任务完成后主动请求预设的URL:
// 任务完成后回调
function callBack($result, $callbackUrl) {
$ch = curl_init($callbackUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($result),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $httpCode == 200;
}
使用闭包(Closure)回调
class TaskProcessor {
public function process($taskId, callable $callback) {
// 执行任务...
$result = $this->executeTask($taskId);
// 调用回调
if (is_callable($callback)) {
$callback($result);
}
}
}
// 使用
$processor = new TaskProcessor();
$processor->process(123, function($result) {
echo "任务完成: " . json_encode($result);
});
使用回调接口(更面向对象)
interface TaskCallback {
public function onSuccess($result);
public function onFailure($error);
}
class TaskHandler {
private $callback;
public function __construct(TaskCallback $callback) {
$this->callback = $callback;
}
public function execute($taskId) {
try {
$result = $this->doWork($taskId);
$this->callback->onSuccess($result);
} catch (Exception $e) {
$this->callback->onFailure($e->getMessage());
}
}
}
// 使用
class MyCallback implements TaskCallback {
public function onSuccess($result) {
// 成功处理
echo "Success: " . json_encode($result);
}
public function onFailure($error) {
// 失败处理
echo "Error: " . $error;
}
}
$handler = new TaskHandler(new MyCallback());
$handler->execute(456);
异步任务队列 + 回调
使用消息队列(如Redis或RabbitMQ):
// 添加任务到队列
$taskData = [
'id' => uniqid(),
'type' => 'process_image',
'params' => ['url' => '...'],
'callback_url' => 'https://your-api.com/callback'
];
// 生产者
$redis->lpush('task_queue', json_encode($taskData));
// 消费者(worker.php)
while (true) {
$task = $redis->brpop('task_queue', 0);
$taskData = json_decode($task[1], true);
// 处理任务...
$result = processTask($taskData['params']);
// 回调
callBack($result, $taskData['callback_url']);
}
使用Promise模式(需要扩展)
使用ReactPHP或Guzzle Promise:
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
// 使用Guzzle异步请求
$client = new Client();
$promises = [];
// 发起多个请求
foreach ($tasks as $task) {
$promises[] = $client->getAsync($task['url'])
->then(function ($response) use ($task) {
echo "Task {$task['id']} completed";
// 处理结果
return $response->getBody();
});
}
// 等待所有完成
$results = Promise\unwrap($promises);
标准Webhook实现(完整示例)
<?php
class WebhookCallback {
private $callbackUrl;
private $secretKey;
public function __construct($callbackUrl, $secretKey) {
$this->callbackUrl = $callbackUrl;
$this->secretKey = $secretKey;
}
public function send($event, $data) {
$payload = [
'event' => $event,
'data' => $data,
'timestamp' => time()
];
return $this->httpPost($payload);
}
private function httpPost($payload) {
$json = json_encode($payload);
$signature = hash_hmac('sha256', $json, $this->secretKey);
$ch = curl_init($this->callbackUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Signature: ' . $signature,
'X-Event-Type: ' . $payload['event']
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 10
]);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 记录回调结果
$this->logCallback($payload, $httpCode, $result);
return $httpCode == 200;
}
private function logCallback($payload, $httpCode, $response) {
// 记录到日志
$logEntry = sprintf(
"[%s] Callback to %s returned %d: %s\n",
date('Y-m-d H:i:s'),
$this->callbackUrl,
$httpCode,
substr($response, 0, 500)
);
file_put_contents('callback.log', $logEntry, FILE_APPEND);
}
}
// 使用示例
$callback = new WebhookCallback(
'https://partner-api.com/result',
'your-secret-key-123'
);
// 任务完成后回调
$result = [
'task_id' => 'task_123456',
'status' => 'completed',
'output' => [
'processed_file' => 'output.pdf',
'size' => 1024000
],
'duration' => 12.5 // seconds
];
$success = $callback->send('task.completed', $result);
if ($success) {
echo "回调成功";
} else {
echo "回调失败,已记录日志";
}
最佳实践建议
- 幂等性:回调接口应该支持重复调用
- 超时处理:设置合理的超时时间
- 重试机制:失败后自动重试
- 安全验证:使用签名验证回调来源
- 异步处理:避免在主流程中同步回调
选择哪种方式取决于你的具体需求:如果是简单的内部调用,闭包回调就够用;如果是跨系统调用,Webhook是标准做法;如果需要高并发,建议使用消息队列异步处理。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播