# AMPHP v2 → v3 Migration **Do NOT follow any v2 patterns.** If you see them in existing code, rewrite them. | v2 (old, WRONG) | v3 (current, correct) | |---|---| | `Amp\Loop::run()` | `Revolt\EventLoop::run()` | | `yield $promise` | `$future->await()` or `async(fn() => ...)` | | `Promise` interface | `Future` class | | `Coroutine`, generators | PHP Fibers, `async()` | | `Amp\call(fn() { yield ... })` | `async(fn() { ... })` | | `Deferred->resolve()` | `DeferredFuture->complete()` | | `Deferred->reject()` | `DeferredFuture->error()` | | `$amp->asyncCall()`, `asyncCoroutine()` | `async()` | | `Amp\Promise\wait()` | `$future->await()` inside fiber or `EventLoop::run(fn() => ...)` | | `Amp\Iterator` | `Amp\Pipeline\Queue` / `Pipeline::fromIterable()` | | `Amp\Emitter` | `Amp\Pipeline\Queue` | | `Amp\Loop::defer()` | `Revolt\EventLoop::defer()` | | `Amp\Loop::delay()` | `Revolt\EventLoop::delay()` | | `$promise->onResolve(fn($err, $val) => ...)` | `$future->map(fn($val) => ...)->catch(fn($e) => ...)` | ## v3 Minimum Requirements ```json { "require": { "php": ">=8.1", "revolt/event-loop": "^1", "amphp/amp": "^3" } } ``` ## How Fibers Replace Generators ```php // v2: generator-based coroutine (WRONG) function fetchData(string $url): \Amp\Promise { return Amp\call(function () use ($url) { $response = yield $httpClient->request($url); return yield $response->getBody()->buffer(); }); } // v3: PHP Fiber (correct) function fetchData(string $url): string { $response = $httpClient->request(new Request($url)); return $response->getBody()->buffer(); // suspends fiber, not the whole thread } ```