Method
phasync::onScopeChange
Registers $fn to be called when the current Scope changes as the event loop switches coroutines.
Description#
public static phasync::onScopeChange(
callable $fn
): voidIt is called as $fn(Scope $new, ?Scope $old) before a coroutine runs, when the scope that is current in it differs from the one current where the loop last switched: when a coroutine starts or resumes in another scope than the coroutine that ran before. A nested run() entered in another scope ($scope->run(fn () => phasync::run($fn)), as a server enters a request) calls it too, before $fn runs. Switches between coroutines of one scope call nothing. It is the place to swap state that PHP keeps globally in and out per operation (a locale, a static of a library that is not scope-aware). Otherwise $scope->run() entered or left inside a coroutine calls nothing: code that does so makes the change itself.
The hooks run in the event loop, outside any coroutine, in the order registered: they must not wait (a wait there throws LogicException), and an exception from one ends phasync::run(). They stay registered for the life of the event loop.
A generator runs in the scope of the code that iterates it (fiber-interop/scope's polyfill gap), and resuming one calls nothing. Reporting a generator's own scope is planned for the phasync extension.
Parameters#
- $fn callable
Examples#
$locales = new WeakMap(); // per Scope
phasync::onScopeChange(function (Scope $new) use ($locales) {
Locale::setDefault($locales[$new] ?? 'en');
});See also#
phasync::goStarts$fnas a coroutine in the current frame and scope, and returns it, without waiting for it.
Used in#
- Making your application safe for concurrent requestsAn adapter running your framework correctly under Swerve doesn't make your own code safe for requests that overlap. The checklist, with a fix for each item.
- Per-request state: Scope and WeakMapKey state by the request's Scope in a WeakMap: each request sees its own value, and the entry goes when the request ends.