PHP异步

Mattakushi4322026-10-26查看 925复制 905

何时激活:PHP 并发、ReactPHP、Swoole 协程、PHP Fibers、异步 PHP、排队作业、Laravel 队列、Symfony Messenger、非阻塞 I/O、事件循环

Download (.md)

📘如何使用这个技能

  1. 1
    复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
  2. 2
    打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
  3. 3
    粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
  4. 4
    直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景

💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。

SKILL.md4590 chars
---
name: php-async
description: "When to activate: PHP concurrency, ReactPHP, Swoole coroutines, PHP Fibers, async PHP, queued jobs, Laravel queues, Symfony Messenger, non-blocking I/O, event loop"
origin: zakr
metadata:
  namespace: zakr/devtools-pack
  version: 1.0.0
  category: engineering
  language: php
  platforms: [claude-code, codex, gemini-cli, cursor, aider, windsurf]
---

# PHP Async & Concurrency Patterns

## When to Use

Deciding how to handle concurrent or long-running work in PHP: background jobs, high-throughput I/O-bound services, or evaluating whether async PHP is even the right tool for the problem.

## Core Patterns

### Default to Queued Jobs, Not Async I/O

For the vast majority of PHP apps (Laravel, Symfony), the pragmatic concurrency model is: handle the HTTP request synchronously and push slow work onto a queue.

```php
// Laravel
final class SendInvoiceEmail implements ShouldQueue
{
    public function __construct(private readonly int $invoiceId)
    {
    }

    public function handle(InvoiceMailer $mailer): void
    {
        $mailer->send(Invoice::findOrFail($this->invoiceId));
    }
}

SendInvoiceEmail::dispatch($invoice->id);
```

```php
// Symfony Messenger
final class SendInvoiceEmailHandler
{
    public function __invoke(SendInvoiceEmail $message): void
    {
        $this->mailer->send($message->invoiceId);
    }
}
```

This scales horizontally (more workers), survives process crashes (the job stays in the queue), and needs no exotic runtime.

### Fibers (PHP 8.1+)

Fibers give you cooperative, pausable execution without an external extension — the primitive that libraries like ReactPHP/Amp build on.

```php
$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('paused');
    echo "Resumed with: {$value}\n";
});

$paused = $fiber->start();   // runs until suspend(), returns 'paused'
$fiber->resume('hello');     // resumes, prints "Resumed with: hello"
```

Most application code should not touch Fibers directly — they're the foundation async libraries use internally.

### ReactPHP: Event-Loop Based Async I/O

```php
$loop = React\EventLoop\Loop::get();

$client = new React\Http\Browser($loop);
$client->get('https://api.example.com/status')
    ->then(function (Psr\Http\Message\ResponseInterface $response) {
        echo $response->getBody();
    });

$loop->run();
```

Useful for long-running daemons (webhooks relay, WebSocket server) that need many concurrent non-blocking connections without spawning a process per connection.

### Swoole Coroutines

```php
Swoole\Coroutine\run(function () {
    [$a, $b] = Swoole\Coroutine\Barrier::wait(
        Swoole\Coroutine::create(fn () => Http\get('https://api.a.com')),
        Swoole\Coroutine::create(fn () => Http\get('https://api.b.com')),
    );
});
```

Swoole rewrites the runtime (its own coroutine-aware sockets, `Co\run`), replacing PHP-FPM entirely. This buys much higher throughput for I/O-bound workloads but is a bigger operational commitment — a different deployment model, different debugging tools, and libraries must be coroutine-safe.

## When NOT to Reach for Async PHP

- A typical CRUD web app with normal request volume — PHP-FPM's process-per-request model is simpler to reason about and debug
- CPU-bound work (image processing, PDF generation) — async doesn't help; use queued workers or a separate service
- When the team has no operational experience running Swoole/RoadRunner in production — the debugging story is meaningfully different from stock PHP-FPM
- Anything achievable by "dispatch to a queue and return 202" — simpler, more resilient, and easier to scale than in-process concurrency

## Checklist

- [ ] Slow/external work (email, PDF generation, third-party API calls) is queued, not done inline in the request
- [ ] Jobs are idempotent — safe to retry after a crash mid-execution
- [ ] If using Fibers/ReactPHP/Swoole directly, the team has a debugging and monitoring story for it
- [ ] Swoole/RoadRunner code avoids storing per-request state in static properties (leaks across requests in a long-running worker)

## Quick Reference

| Need | Tool |
|---|---|
| Offload slow work from the request cycle | Laravel Queues / Symfony Messenger |
| Low-level pausable execution primitive | Fibers (PHP 8.1+) |
| Event-loop async I/O in userland PHP | ReactPHP / Amp |
| Maximum throughput, coroutine-native runtime | Swoole / OpenSwoole |
| "Just handle more requests" | Scale PHP-FPM workers horizontally first |

## See Also

- `skills/php-ecosystem/laravel-patterns.md`
- `skills/php-ecosystem/php-performance.md`
来源:skillsdirectory

评论0

登录后参与评论

还没有评论,来抢沙发吧