A non-blocking concurrency framework for PHP applications. ๐Ÿ˜

Overview
Amp Logo

Amp

Amp is a non-blocking concurrency framework for PHP. It provides an event loop, promises and streams as a base for asynchronous programming.

Promises in combination with generators are used to build coroutines, which allow writing asynchronous code just like synchronous code, without any callbacks.

Motivation

Traditionally, PHP has a synchronous execution flow, doing one thing at a time. If you query a database, you send the query and wait for the response from the database server in a blocking manner. Once you have the response, you can start doing the next thing.

Instead of sitting there and doing nothing while waiting, we could already send the next database query, or do an HTTP call to an API.

Making use of the time we usually spend on waiting for I/O can speed up the total execution time. The following diagram shows the execution flow with dependencies between the different tasks, once executed sequentially and once concurrently.

Amp allows such concurrent I/O operations while keeping the cognitive load low by avoiding callbacks. Instead, the results of asynchronous operations can be awaited using yield resulting in code which is structured like traditional blocking I/O code while the actual execution flow is handled by Amp.

Installation

This package can be installed as a Composer dependency.

composer require amphp/amp

This installs the basic building blocks for asynchronous applications in PHP. We offer a lot of repositories building on top of this repository, e.g.

Documentation

Documentation can be found on amphp.org as well as in the ./docs directory. Each packages has it's own ./docs directory.

Requirements

This package requires PHP 7.0 or later. Many of the other packages raised their requirement to PHP 7.1. No extensions required!

Optional Extensions

Extensions are only needed if your app necessitates a high numbers of concurrent socket connections, usually this limit is configured up to 1024 file descriptors.

Examples

Examples can be found in the ./examples directory of this repository as well as in the ./examples directory of our other libraries.

Versioning

amphp/amp follows the semver semantic versioning specification like all other amphp packages.

2.x

Supported. We don't have plans to release v3, yet.

1.x

No longer supported. We stopped providing bug fixes 2017-12-31 and stopped providing security fixes 2018-12-31.

Compatible Packages

Compatible packages should use the amphp topic on GitHub.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

License

The MIT License (MIT). Please see LICENSE for more information.

Comments
  • Amp v3 with ext-fiber support

    Amp v3 with ext-fiber support

    The author and ext-async extension disappeared for unknown reasons https://github.com/concurrent-php/ext-async, which is very sad.

    Thanks to others, the fork is available: https://github.com/dreamsxin/ext-async

    @kelunik is there still a plan to implement the 3rd version with ext-async support? Here are some mentions about 3rd version plans:

    1. https://github.com/amphp/amp/issues/253#issuecomment-449875440
    2. https://github.com/amphp/amp/issues/229#issuecomment-448705155

    Thanks!

    question discussion v3.x 
    opened by dbalabka 35
  • Version 2 Review

    Version 2 Review

    @trowski @bwoebi @rdlowrey I reviewed Amp v2.0 and here are my comments.

    Internal\WhenQueue

    How important is the layer of indirection? If we're worried about the call stack, should we instead resolve promises asynchronously?

    It could also be renamed to a more generic name like CallbackQueue or CallQueue.

    Internal\Placeholder

    Annotation for $onResolved is callable|\Amp\Internal\WhenQueue|null, should be ?WhenQueue or ?WhenQueue|null instead.

    Coroutine

    Why does it not accept a callable as constructor parameter in addition of generators?

    Emitter

    if ($this->resolved) {
        return;
    }
    

    ^ Does that ignore double resolution silently?

    Pause

    Do we really need $value there? What about keep_alive = false?

    Internal\LazyPromise

    Why is this one internal? Why is Amp\lazy suggested to be used only? Why do we even have Amp\lazy? Instead of using arguments to Amp\lazy, those parameters can just be use'd in a closure by the user instead of providing them as arguments.

    Amp\wrap vs. Amp\coroutine

    It is weird to have both and usage will be confusion for users.

    Amp\timeout

    I think Amp\timeout shouldn't keep the loop running. The watchers should probably be unreferenced.

    Amp\lift

    Do we need lift? I always ask that when reading the docs regarding it.

    Amp\filter

    Amp\filter filters observables now instead of promises.

    opened by kelunik 25
  • Support for Guzzle / generic promise adaption

    Support for Guzzle / generic promise adaption

    Guzzle promises implement A+ promises but are no react promises. How about supporting them as well or more generic all vendor-promises that implement "then()"? Instead of $result instanceof ReactPromise you would write e.g. isVendorPromise($result). adapt() handles any object that implements done() or then() anyway.

    Any opinions?

    feature request 
    opened by brstgt 24
  • Changing

    Changing "when" to "onResolve" or "onComplete"

    It doesn't matter for normal promises, but I think it matters for more advanced use cases where the promise API is just one way of consumption. Looking at a list of functions, onResolve / onComplete are way more expressive than when.

    change request discussion 
    opened by kelunik 20
  • Promise\wait together with Promise\rethrow

    Promise\wait together with Promise\rethrow

    (copied from irc)

    hi folks php: src/unix/core.c:896: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed. what does that tell me?

    this happened to me once I added some new tests today but it appeared on old tests so I encounter this only when running the whole test-suite I switched to EV and the problem disappeared seems to be a bug in UV ?

    I wrote 2 new test classes today, one results in to uv error above, which I can prevent by switching to ev the second one makes a bunch of old tests red, when I start the whole test-suite, but they will all be green again, when I exclude this one so weird

    mmh... seems to have something to do with using wait(call(...)) within the tests, and inside the lib I do Promise\rethrow($subscription->start()); somewhere when I don't to the rethrow thing, then the other tests are green again

    I can make the tests pass with a different Promise\wait implementation check this out please

    function wait($promise) {
            if (!$promise instanceof Promise) {
                if ($promise instanceof ReactPromise) {
                    $promise = adapt($promise);
                } else {
                    throw createTypeError([Promise::class, ReactPromise::class], $promise);
                }
            }
    
            $resolved = false;
            $wait = true;
            $exception = null;
            $value = null;
    
            $promise->onResolve(function ($e, $v) use (&$resolved, &$value, &$exception, &$wait) {
                $resolved = true;
                $exception = $e;
                $value = $v;
                $wait = false;
                Loop::stop();
            });
    
            while($wait) {
                Loop::run();
            }
    
            if ($exception) {
                throw $exception;
            }
    
            return $value;
        }
    

    but uv still is a problem

    question 
    opened by prolic 17
  • Make resolve() accept also callables

    Make resolve() accept also callables

    This is just syntactic sugar around resolve() for use with a generator closure to avoid temporary variables.

    Instead of having to write:

    $var = function() {
        yield;
    };
    return resolve($var);
    

    you can simply write:

    return promise(function() {
        yield;
    });
    

    I'm not married to the function name if it doesn't suit, but this is an option I have found frustratingly missing.

    This PR also adds a missing @return tag to the resolve() docblock.

    opened by DaveRandom 17
  • Async programming with blocking operations

    Async programming with blocking operations

    Hi,

    I am trying to figure out how to get some blocking tasks performed in parallel, the example is here:

    https://gist.github.com/yoanisgil/a28d57abca781fd84af1

    Roughly the script will launch 5 asynchronous tasks (asyncMultiply) each of which will perform a random sleep. When I run the script with:

    time docker run -v $(PWD):/usr/src/myapp  -ti --rm yoanisgil/php56-cli-composer php test.php
    

    it takes about ~ 16 secs, which indicates that tasks are performed synchronously (each task performs a random sleep between 2 - 4 seconds).

    Given the deferred/asynchronous nature of promises and that I'm using Amp\immediately I would have expected about ~ 4 seconds of execution.

    For sure I most be doing something wrong. Any ideas what that might be?

    Bests,

    Yoanis.

    opened by yoanisgil 17
  • Getting access to child process data on SIGCHLD in Loop::onSignal.

    Getting access to child process data on SIGCHLD in Loop::onSignal.

    I'm playing around with launching processes in a fiber, suspending the fiber and then restarting the fiber to collect results on SIGCHLD signal based on the child pid/exit code in pcntl_signal(SIGCHLD, ... ).

    I don't see a way to access the terminating child PID in Loop::onSignal() however. Is it possible? It would be a nice feature to have otherwise.

    With the event loop I'm now resuming all fibers on SIGCHLD in Loop::onSignal and suspending them again immediately inside the fiber.

    question 
    opened by whataboutpereira 16
  • Question: Does yield always wait?

    Question: Does yield always wait?

    Does yield always wait until all yielded commands are finished? Or is it possible to yield and continue running the function while the yielded command runs concurrently?

    opened by olleharstedt 16
  • Doing async job while sending http request

    Doing async job while sending http request

    Hi there! I am trying to understand whether it is possible to do some async job while sending async http request in the same Loop of the same php process.

    My goal is to iterate over a long array and filter it by "evaluating" each item (time & cpu consuming op). Filtered items contain a url that should be requested. But to avoid awaiting for response I could continue iterating meanwhile. I've tried using producer/consumer pattern but "yield $client->request()" blocks everything. Is there a way of handling such task?

    opened by proArtex 16
  • Add more generic phpdocs

    Add more generic phpdocs

    See #305

    This allows:

    interface WatcherProcess
    {
        public function stop(): void;
    
        /**
         * @return Promise<?ModifiedFile>
         */
        public function wait(): Promise;
    }
    
    opened by dantleech 16
  • QUIC support

    QUIC support

    Hello,

    My point of view on amphp is that this project pushes always PHP limits further, and I love it. I think it's time to talk about a support of QUIC so amp can support HTTP/3 as well.

    For the record, QUIC is already supported in some languages, see Wikipedia: https://en.wikipedia.org/wiki/QUIC#Source_code

    What do you think about that? Do you have any plan for its support? I assume it should be a package on top of the UDP library of amp.

    feature request 
    opened by Nek- 2
  • EvLoop::io(): 9 bytes of buffered data lost during stream conversion!

    EvLoop::io(): 9 bytes of buffered data lost during stream conversion!

    EvLoop::io(): 9 bytes of buffered data lost during stream conversion!, /home/shared/vendor/amphp/amp/lib/Loop/EvDriver.php:253
    
    $ pecl list
    Installed packages, channel pecl.php.net:
    =========================================
    Package Version State
    ev      1.1.2   stable
    pq      2.1.8   stable
    raphf   2.0.1   stable
    
    opened by PNixx 8
  • Allow signal handling for Uv w/o 100% cpu usage

    Allow signal handling for Uv w/o 100% cpu usage

    Ref #329

    To be honest this could lend itself to its own Uv specific example file, but here's something that could work regardless of driver used.

    Again, downside is that the end of code execution is not in the signal handling function, but sometime after the Loop::run() line.

    opened by duckboy81 9
  • UvDriver warnings

    UvDriver warnings

    I just got these warnings:

    PHP Warning:  uv_update_time(): passed UVLoop handle is already closed in .../vendor/amphp/amp/lib/Loop/UvDriver.php on line 193
    PHP Warning:  uv_now(): passed UVLoop handle is already closed in .../vendor/amphp/amp/lib/Loop/UvDriver.php on line 196
    

    It happened right after an uncaught exception was thrown. Both warnings appeared several times. Then the process finally stopped.

    bug v2.x 
    opened by enumag 1
  • Adding documentation for static analysis tools

    Adding documentation for static analysis tools

    Hey,

    Has any thought been given to supporting phpstan/psalm generics e.g.

    class Foo
    {
        /**
         * @return Promise<MyDomainThing>
         */
        public function wait(): Promise { // ... }
    }
    

    Otherewise, what's the best way to document a Promise that's compatible with SA tools?

    Psalm has some stubs for Amp: https://github.com/vimeo/psalm/blob/master/src/Psalm/Internal/Stubs/Amp.php

    documentation 
    opened by dantleech 3
Releases(v3.0.0)
  • v3.0.0(Dec 18, 2022)

    Event Loop

    Amp no longer ships its own event loop. It's now based on Revolt. Revolt\EventLoop is quite similar to Amp's previous Amp\Loop. A very important difference is using float $seconds instead of int $milliseconds for timers though!

    Promises

    Future is a replacement for the previous Promise. There's no need for callbacks or yield anymore! Its await() method is based on fibers and replaces generator based coroutines / Amp\Promise\wait().

    • Renamed Amp\Deferred to Amp\DeferredFuture.
    • Removed Amp\Promise\wait(): Use Amp\Future::await() instead, which can be called in any (nested) context unlike before.
    • Removed Amp\call(): Remove the passed closure boilerplate and all yield keywords, interruption is handled via fibers now instead of generator coroutines.
    • Removed Amp\asyncCall(): Replace invocations with Amp\async(), which starts a new fiber instead of using generators.
    • Removed Amp\coroutine(): There's no direct replacement.
    • Removed Amp\asyncCoroutine(): There's no direct replacement.
    • Removed Amp\Promise\timeout(): Future::await() accepts an optional Cancellation, which can be used as a replacement.
    • Removed Amp\Promise\rethrow(): Unhandled errors are now automatically thrown into the event loop, so there's no need for that function anymore.
    • Unhandled errors can be ignored using Future::ignore() if needed, but should usually be handled in some way.
    • Removed Amp\Promise\wrap(): Use Future::finally() instead.
    • Renamed Amp\getCurrentTime() to Amp\now() returning the time in seconds instead of milliseconds.
    • Changed Amp\delay() to accept the delay in seconds now instead of milliseconds.
    • Added Amp\weakClosure() to allow a class to hold a self-referencing Closure without creating a circular reference that prevents automatic garbage collection.
    • Added Amp\trapSignal() to await one or multiple signals.

    Promise Combinators

    Promise combinators have been renamed:

    • Amp\Promise\race() has been renamed to Amp\Future\awaitFirst()
    • Amp\Promise\first() has been renamed to Amp\Future\awaitAny()
    • Amp\Promise\some() has been renamed to Amp\Future\awaitAnyN()
    • Amp\Promise\any() has been renamed to Amp\Future\awaitAll()
    • Amp\Promise\all() has been renamed to Amp\Future\await()

    CancellationToken

    • CancellationToken has been renamed to Cancellation.
    • CancellationTokenSource has been renamed to DeferredCancellation.
    • NullCancellationToken has been renamed to NullCancellation.
    • TimeoutCancellationToken has been renamed to TimeoutCancellation.
    • CombinedCancellationToken has been renamed to CompositeCancellation.
    • SignalCancellation has been added.

    Iterators

    Iterators have been removed from amphp/amp as normal PHP iterators can be used with fibers now and there's no need for a separate API. However, there's still some need for concurrent iterators, which is covered by the new amphp/pipeline library now.

    Closable

    Amp\Closable has been added as a new basic interface for closable resources such as streams or sockets.

    Strict Types

    Strict types now declared in all library files. This will affect callbacks invoked within this library's code which use scalar types as parameters. Functions used with Amp\async() are the most likely to be affected by this change โ€” these functions will now be invoked within a strict-types context.

    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta.11(Dec 16, 2022)

    • Removed circular dependency on amphp/phpunit-util (#408).
    • Added stack-trace of Future creation to UnhandledFutureError which is defined only when assertions are enabled (#405).
    • Strict types now declared in all library files. This will affect callbacks invoked within this library's code which use scalar types as parameters. Functions used with Amp\async() are the most likely to be affected by this change โ€” these functions will now be invoked within a strict-types context.
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta.10(Nov 7, 2022)

    What's Changed

    • Allow GC of arguments during async() closure execution (https://github.com/amphp/amp/pull/395)
    • Support revolt 1.x, declare incompatibility with revolt 0.1.x
    • Change Future::ignore() to be a fluent interface (https://github.com/amphp/amp/pull/403)
    • Improve template types

    Full Changelog: https://github.com/amphp/amp/compare/v3.0.0-beta.9...v3.0.0-beta.10

    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta.9(Jul 12, 2022)

    • Fixed circular reference in async() on exceptions (https://github.com/amphp/amp/issues/394)
    • Removed deprecated combinator functions:
      • Amp\Future\race โ†’ Amp\Future\awaitFirst
      • Amp\Future\any โ†’ Amp\Future\awaitAny
      • Amp\Future\some โ†’ Amp\Future\awaitAnyN
      • Amp\Future\settle โ†’ Amp\Future\awaitAll
      • Amp\Future\all โ†’ Amp\Future\await
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta.8(Jun 25, 2022)

    • Fixed weakClosure() not preserving scope when using a Closure with scope limited to a parent class (#393)
    • Fixed regression in beta 9 where CompositeCancellation would return false from isRequested() and not throw from throwIfRequested() after cancellation was requested
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta.7(Jun 16, 2022)

    • Added SignalCancellation that triggers a cancellation when a particular signal is received by the process.
    • Fixed an issue in CombinedCancellation where subsequent cancellation of another Cancellation in the set could alter the exception used to cancel the token.
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta.6(Apr 23, 2022)

  • v3.0.0-beta.5(Apr 3, 2022)

    • Added Closable interface for closable resources such as streams (the interface of the same name will be removed from amphp/byte-stream in a future release) (#387)
    Source code(tar.gz)
    Source code(zip)
  • v2.6.2(Feb 20, 2022)

  • v3.0.0-beta.4(Jan 16, 2022)

    Note: This is a pre-release, there might be breaking changes in the final stable version.

    • Mark Future template parameter as covariant
    • Add compatibility with revolt/event-loop v0.2.x
    • Improve exception message of UnhandledFutureError
    • Cancel DeferredCancellation when destroyed (#382)
    • Rename combinators, introduce CompositeLengthException (#383)
      • race โ†’ awaitFirst
      • any โ†’ awaitAny
      • some โ†’ awaitAnyN
      • settle โ†’ awaitAll
      • all โ†’ await
      • The old names have been kept for a migration phase, but will be removed before the final v3 release.
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta.3(Dec 22, 2021)

  • v3.0.0-beta.2(Dec 3, 2021)

    Note: This is a pre-release, there might be breaking changes in the final stable version.

    • Fixed revolt/event-loop dependency declaration to use released ^0.1 version.
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta.1(Dec 3, 2021)

    Note: This is a pre-release, there might be breaking changes in the final stable version.

    Event Loop

    Amp no longer ships its own event loop. It's now based on Revolt. Revolt\EventLoop is quite similar to Amp's previous Amp\Loop. A very important difference is using float $seconds instead of int $milliseconds for timers.

    Futures

    Future is a replacement for the previous Promise. It's await() method is based on fibers and replaces generator based coroutines / Amp\Promise\wait().

    • await() accepts an optional Cancellation, which can be used as a replacement for Amp\Promise\timeout().
    • Unhandled errors are now automatically thrown into the event loop, so there's no need for Amp\Promise\rethrow() anymore.
    • Unhandled errors can be ignored using Future::ignore().

    Cancellation

    • CancellationToken has been renamed to Cancellation
    • CancellationTokenSource has been renamed to DeferredCancellation
    • NullCancellationToken has been renamed to NullCancellation
    • TimeoutCancellationToken has been renamed to TimeoutCancellation
    • CombinedCancellationToken has been renamed to CompositeCancellation
    Source code(tar.gz)
    Source code(zip)
  • v2.6.1(Sep 23, 2021)

    • Fixed destructor issue in EventDriver (#358)
    • Fixed EventDriver feature configuration to work with different kinds of FDs, e.g. under certain conditions in docker containers (#360)
    Source code(tar.gz)
    Source code(zip)
  • v2.6.0(Jul 16, 2021)

  • v2.5.2(Jan 10, 2021)

    • Ignore only stream_select errors due to signal interruptions (#338) Fixes stream_select handling on signal interruptions on PHP 8 and avoids suppressing errors that shouldn't be suppressed.
    • Improve type definition for combinators (any, first, some) (#334)
    • Removed internal `TimerQueueEntry
    Source code(tar.gz)
    Source code(zip)
  • v2.5.1(Nov 3, 2020)

    • Fixed issue where cancelling timer watchers in NativeDriver could result in timers being executed out of order (#332)
    • Fixed 100% CPU usage in NativeDriver when only signal watchers were enabled
    Source code(tar.gz)
    Source code(zip)
  • v2.5.0(Jul 14, 2020)

    • Add Amp\Iterator\discard() (#315)
    • Fix potential warning on shutdown in UvDriver
    • Fix repeat watchers in NativeDriver that are disabled and re-enabled during callback invocation (#325)
    • Fix timer intervals being counted from timer creation instead of last tick time (#319)
    • Loop::now() / Driver::now() is no longer cached in each tick
    Source code(tar.gz)
    Source code(zip)
  • v2.4.4(Apr 30, 2020)

    • Fixed Delayed::reference() / Delayed::unreference() after the promise resolved
    • Changed return type of Delayed::reference() / Delayed::unreference() to self to allow fluid API usage
    • Add generics for Amp\Promise\wait
    • Improved types for Amp\call / Amp\coroutine
    Source code(tar.gz)
    Source code(zip)
  • v2.4.3(Apr 19, 2020)

  • v2.4.2(Apr 4, 2020)

    • Provide useful exception trace in TimeoutCancellationToken (#303)
    • Add parameter for custom timeout message (#299)
    • Add psalm annotations for improved static analysis
    Source code(tar.gz)
    Source code(zip)
  • v2.4.1(Feb 13, 2020)

  • v2.4.0(Nov 11, 2019)

    • Added getCurrentTime() as public API, providing millisecond timestamps for runtime measurements with special support for 32 bit systems. Returned timestamps are relative to an arbitrary point in time, so this API is only suitable to compare two timestamps generated in the same process.
    Source code(tar.gz)
    Source code(zip)
  • v2.3.2(Oct 26, 2019)

  • v2.3.1(Oct 1, 2019)

  • v2.3.0(Oct 1, 2019)

    • Added TracingDriver to debug (hanging) tests / applications. The environment variable AMP_DEBUG_TRACE_WATCHERS=true can be set to automatically create a TracingDriver wrapping the actual driver. TracingDriver::dump() can be used to dump all enabled, referenced watchers keeping the loop running.
    Source code(tar.gz)
    Source code(zip)
  • v2.2.1(Sep 21, 2019)

    • Fixed backpressure release on Emitter::emit(), the backpressure is now released as soon as the value is consumed, instead of the next value being requested.
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Aug 2, 2019)

  • v2.1.2(Jun 10, 2019)

    • Fixed issue where the loop time in NativeDriver was not refreshed after waiting for I/O streams (#256)
    • Fixed compatibility issue of NativeDriver with pcntl_async_signals() (#264)
    • A custom queue is now used for timers in NativeDriver to allow cancelled timers to be garbage collected immediately instead of after their original expiration time (#220)
    • Resolving a promise with an object that throws when destructed will now forward that exception to the event loop error handler (#271)
    • Fixed loop time to support 32-bit systems (#252, #273)
    Source code(tar.gz)
    Source code(zip)
  • v2.1.1(Dec 11, 2018)

Owner
Amp
Asynchronous Multitasking PHP
Amp
๐Ÿš€ Coroutine-based concurrency library for PHP

English | ไธญๆ–‡ Swoole is an event-driven asynchronous & coroutine-based concurrency networking communication engine with high performance written in C++

Swoole Project 17.7k Jan 5, 2023
Revolt is a rock-solid event loop for concurrent PHP applications.

Revolt is a rock-solid event loop for concurrent PHP applications.

Revolt PHP 586 Jan 2, 2023
Infrastructure and testing helpers for creating CQRS and event sourced applications.

Broadway Broadway is a project providing infrastructure and testing helpers for creating CQRS and event sourced applications. Broadway tries hard to n

null 1.5k Dec 27, 2022
An asynchronous event driven PHP socket framework. Supports HTTP, Websocket, SSL and other custom protocols. PHP>=5.3.

Workerman What is it Workerman is an asynchronous event-driven PHP framework with high performance to build fast and scalable network applications. Wo

walkor 10.2k Jan 4, 2023
Icicle is a PHP library for writing asynchronous code using synchronous coding techniques

Icicle is now deprecated in favor of Amp v2.0. This version is is currently under development, but close to release. The v2.0 branches are amp_v2 in a

icicle.io 1.1k Dec 21, 2022
ร‰vรฉnement is a very simple event dispatching library for PHP.

ร‰vรฉnement ร‰vรฉnement is a very simple event dispatching library for PHP. It has the same design goals as Silex and Pimple, to empower the user while st

Igor 1.2k Jan 4, 2023
Asynchronous coroutines for PHP 7.

Recoil An asynchronous coroutine kernel for PHP 7. composer require recoil/recoil The Recoil project comprises the following packages: recoil/api - T

Recoil 787 Dec 8, 2022
A pragmatic event sourcing library for PHP with a focus on developer experience.

EventSaucePHP EventSauce is a somewhat opinionated, no-nonsense, and easy way to introduce event sourcing into PHP projects. It's designed so storage

EventSauce 685 Dec 31, 2022
PHP 7.4 EventStore Implementation

Prooph Event Store Common classes and interface for Prooph Event Store implementations. Installation You can install prooph/event-store via composer b

null 532 Dec 9, 2022
Reactive extensions for PHP.

This package is abandoned. Use https://github.com/ReactiveX/RxPHP instead Rx.PHP Reactive extensions for PHP. The reactive extensions for PHP are a se

Alexander 208 Apr 6, 2021
Golang's defer statement for PHP

PHP Defer A defer statement originally comes from Golang. This library allows you to use defer functionality in PHP code. Usage <?php defer($context,

null 249 Dec 31, 2022
Reactive extensions for PHP

RxPHP Reactive extensions for PHP. The reactive extensions for PHP are a set of libraries to compose asynchronous and event-based programs using obser

ReactiveX 1.6k Dec 12, 2022
PHP Application using DDD CQRS Event Sourcing with Hexagonal Architecture

PHP Application using DDD CQRS Event Sourcing with Hexagonal Architecture Application built with Ecotone Framework and powered by integrations with Pr

EcotoneFramework 65 Dec 27, 2022
A non-blocking concurrency framework for PHP applications. ๐Ÿ˜

Amp is a non-blocking concurrency framework for PHP. It provides an event loop, promises and streams as a base for asynchronous programming. Promises

Amp 3.8k Jan 4, 2023
Event-driven, non-blocking I/O with PHP.

Event-driven, non-blocking I/O with PHP. ReactPHP is a low-level library for event-driven programming in PHP. At its core is an event loop, on top of

ReactPHP 8.5k Jan 8, 2023
Event-driven, non-blocking I/O with PHP.

Event-driven, non-blocking I/O with PHP. ReactPHP is a low-level library for event-driven programming in PHP. At its core is an event loop, on top of

ReactPHP 8.5k Dec 26, 2022
A non-blocking stream abstraction for PHP based on Amp.

amphp/byte-stream is a stream abstraction to make working with non-blocking I/O simple. Installation This package can be installed as a Composer depen

Amp 317 Dec 22, 2022
A simple RESTful non-blocking API, to send and receive money

A simple RESTful non-blocking API, to send and receive money.

Daniel Rodrigues 3 Dec 19, 2022
๐Ÿš€ Coroutine-based concurrency library for PHP

English | ไธญๆ–‡ Swoole is an event-driven asynchronous & coroutine-based concurrency networking communication engine with high performance written in C++

Swoole Project 17.7k Jan 8, 2023
๐Ÿš€ Coroutine-based concurrency library for PHP

English | ไธญๆ–‡ Swoole is an event-driven asynchronous & coroutine-based concurrency networking communication engine with high performance written in C++

Swoole Project 17.7k Jan 5, 2023