PHPAPI任务结果怎么回调

wen PHP项目 15

本文目录导读:

PHPAPI任务结果怎么回调

  1. HTTP异步回调(Webhook)
  2. 使用闭包(Closure)回调
  3. 使用回调接口(更面向对象)
  4. 异步任务队列 + 回调
  5. 使用Promise模式(需要扩展)
  6. 标准Webhook实现(完整示例)
  7. 最佳实践建议

在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 "回调失败,已记录日志";
}

最佳实践建议

  1. 幂等性:回调接口应该支持重复调用
  2. 超时处理:设置合理的超时时间
  3. 重试机制:失败后自动重试
  4. 安全验证:使用签名验证回调来源
  5. 异步处理:避免在主流程中同步回调

选择哪种方式取决于你的具体需求:如果是简单的内部调用,闭包回调就够用;如果是跨系统调用,Webhook是标准做法;如果需要高并发,建议使用消息队列异步处理。

抱歉,评论功能暂时关闭!