本文目录导读:

- Swoole 协程任务
- Workerman 异步任务
- ReactPHP promise 方式
- 使用协程(Coroutine)方式
- 使用 MySQL 异步查询结果
- Redis 异步任务队列
- Swoole 协程 channel 方式
- 关键要点
在 PHP 中获取任务(Task)结果通常取决于你使用的并发/异步模型,以下是几种常见场景和解决方案:
Swoole 协程任务
使用 TaskWorker(异步任务)
<?php
use Swoole\Server;
$server = new Server('127.0.0.1', 9501);
// 设置 task 进程数
$server->set([
'task_worker_num' => 4,
]);
// 投递任务
$server->on('Receive', function ($server, $fd, $reactor_id, $data) {
echo "收到请求,投递任务\n";
// 异步投递任务
$task_id = $server->task("执行任务的数据");
// 清理旧数据
$server->send($fd, "任务已投递,ID: {$task_id}\n");
});
// 处理任务
$server->on('Task', function ($server, $task_id, $reactor_id, $data) {
echo "开始处理任务\n";
// 执行耗时操作
$result = "处理结果:" . $data;
// 返回结果给 Worker 进程
$server->finish($result);
});
// 接收任务结果
$server->on('Finish', function ($server, $task_id, $data) {
echo "任务完成,结果:{$data}\n";
});
$server->start();
同步等待任务结果
<?php
use Swoole\Coroutine;
$scheduler = new Coroutine\Scheduler;
$scheduler->add(function () {
$result = Swoole\Coroutine::create(function () {
// 模拟耗时操作
co::sleep(2);
return "任务结果";
});
echo "结果: " . $result;
});
$scheduler->start();
Workerman 异步任务
使用 AsyncTcpConnection
<?php
use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function ($connection, $data) {
// 建立异步连接
$task_connection = new AsyncTcpConnection('tcp://127.0.0.1:1234');
// 发送任务
$task_connection->send(json_encode(['task' => 'do_something']));
// 接收任务结果
$task_connection->onMessage = function ($task_connection, $task_result) use ($connection) {
$connection->send("任务完成,结果:" . $task_result);
$task_connection->close();
};
$task_connection->connect();
};
Worker::runAll();
ReactPHP promise 方式
<?php
require __DIR__ . '/vendor/autoload.php';
use React\EventLoop\Factory;
use React\Promise\Promise;
$loop = Factory::create();
// 创建异步任务
function asyncTask() {
return new Promise(function ($resolve, $reject) {
// 模拟异步操作
$loop = Factory::create();
$loop->addTimer(2, function () use ($resolve) {
$resolve("任务结果");
});
});
}
// 调用任务
$promise = asyncTask();
// 获取结果
$promise->then(
function ($result) {
echo "任务结果: " . $result;
},
function ($error) {
echo "任务失败: " . $error;
}
);
$loop->run();
使用协程(Coroutine)方式
<?php
use Swoole\Coroutine;
// 创建协程
Coroutine::create(function () {
// 使用 Go 函数
$result = go(function () {
// 模拟耗时操作
Coroutine::sleep(2);
return "协程任务结果";
});
// 等待并获取结果
$data = $result->get();
echo "获取到结果: " . $data;
});
使用 MySQL 异步查询结果
<?php
use Swoole\Coroutine\MySQL;
$swoole_mysql = new MySQL();
$swoole_mysql->connect([
'host' => '127.0.0.1',
'user' => 'root',
'password' => 'password',
'database' => 'test',
]);
// 异步查询
$result = $swoole_mysql->query('SELECT * FROM users WHERE id=1');
// 获取结果
$data = $result ? $swoole_mysql->fetch() : null;
echo "查询结果: " . json_encode($data);
Redis 异步任务队列
<?php
use Swoole\Coroutine\Redis;
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 生产任务
$task_id = uniqid();
$redis->lpush('task_queue', json_encode(['id' => $task_id, 'data' => '任务数据']));
// 异步消费
Coroutine::create(function () use ($redis) {
while (true) {
$result = $redis->brpop('task_queue', 1);
if ($result) {
echo "获取到任务: " . $result[1] . PHP_EOL;
// 处理任务...
}
Coroutine::sleep(0.1);
}
});
Swoole 协程 channel 方式
<?php
use Swoole\Coroutine;
$channel = new Coroutine\Channel(10);
// 生产者
Coroutine::create(function () use ($channel) {
// 模拟耗时任务
$channel->push("任务结果1");
$channel->push("任务结果2");
$channel->close();
});
// 消费者
Coroutine::create(function () use ($channel) {
while ($data = $channel->pop()) {
echo "获取到结果:" . $data . PHP_EOL;
}
});
Coroutine\run();
关键要点
- 异步模型选择:根据需求选择适合的并发模型
- 错误处理:总是添加错误处理逻辑
- 超时控制:设置合理的超时时间
- 资源清理:记得释放连接和资源
- 日志记录:记录任务执行状态
根据你的具体框架和需求,选择适合的方案,如果需要更详细的示例,请提供你的技术栈。