Lightweight library that eases using components built for ReactPHP in a traditional, blocking environment.

Overview

clue/reactphp-block

CI status installs on Packagist

Lightweight library that eases integrating async components built for ReactPHP in a traditional, blocking environment.

ReactPHP provides you a great set of base components and a huge ecosystem of third party libraries in order to perform async operations. The event-driven paradigm and asynchronous processing of any number of streams in real time enables you to build a whole new set of application on top of it. This is great for building modern, scalable applications from scratch and will likely result in you relying on a whole new software architecture.

But let's face it: Your day-to-day business is unlikely to allow you to build everything from scratch and ditch your existing production environment. This is where this library comes into play:

Let's block ReactPHP More specifically, this library eases the pain of integrating async components into your traditional, synchronous (blocking) application stack.

Table of contents

Support us

We invest a lot of time developing, maintaining and updating our awesome open-source projects. You can help us sustain this high-quality of our work by becoming a sponsor on GitHub. Sponsors get numerous benefits in return, see our sponsoring page for details.

Let's take these projects to the next level together! 🚀

Quickstart example

The following example code demonstrates how this library can be used along with an async HTTP client to process two non-blocking HTTP requests and block until the first (faster) one resolves.

function blockingExample()
{
    // this example uses an HTTP client
    // this could be pretty much everything that binds to an event loop
    $browser = new React\Http\Browser();

    // set up two parallel requests
    $request1 = $browser->get('http://www.google.com/');
    $request2 = $browser->get('http://www.google.co.uk/');

    // keep the loop running (i.e. block) until the first response arrives
    $fasterResponse = Clue\React\Block\awaitAny(array($request1, $request2));

    return $fasterResponse->getBody();
}

Usage

This lightweight library consists only of a few simple functions. All functions reside under the Clue\React\Block namespace.

The below examples refer to all functions with their fully-qualified names like this:

Clue\React\Block\await(…);

As of PHP 5.6+ you can also import each required function into your code like this:

use function Clue\React\Block\await;

await(…);

Alternatively, you can also use an import statement similar to this:

use Clue\React\Block;

Block\await(…);

sleep()

The sleep(float $seconds, ?LoopInterface $loop = null): void function can be used to wait/sleep for $time seconds.

Clue\React\Block\sleep(1.5, $loop);

This function will only return after the given $time has elapsed. In the meantime, the event loop will run any other events attached to the same loop until the timer fires. If there are no other events attached to this loop, it will behave similar to the built-in sleep().

Internally, the $time argument will be used as a timer for the loop so that it keeps running until this timer triggers. This implies that if you pass a really small (or negative) value, it will still start a timer and will thus trigger at the earliest possible time in the future.

This function takes an optional LoopInterface|null $loop parameter that can be used to pass the event loop instance to use. You can use a null value here in order to use the default loop. This value SHOULD NOT be given unless you're sure you want to explicitly use a given event loop instance.

Note that this function will assume control over the event loop. Internally, it will actually run() the loop until the timer fires and then calls stop() to terminate execution of the loop. This means this function is more suited for short-lived program executions when using async APIs is not feasible. For long-running applications, using event-driven APIs by leveraging timers is usually preferable.

await()

The await(PromiseInterface $promise, ?LoopInterface $loop = null, ?float $timeout = null): mixed function can be used to block waiting for the given $promise to be fulfilled.

$result = Clue\React\Block\await($promise);

This function will only return after the given $promise has settled, i.e. either fulfilled or rejected. In the meantime, the event loop will run any events attached to the same loop until the promise settles.

Once the promise is fulfilled, this function will return whatever the promise resolved to.

Once the promise is rejected, this will throw whatever the promise rejected with. If the promise did not reject with an Exception, then this function will throw an UnexpectedValueException instead.

try {
    $result = Clue\React\Block\await($promise);
    // promise successfully fulfilled with $result
    echo 'Result: ' . $result;
} catch (Exception $exception) {
    // promise rejected with $exception
    echo 'ERROR: ' . $exception->getMessage();
}

See also the examples.

This function takes an optional LoopInterface|null $loop parameter that can be used to pass the event loop instance to use. You can use a null value here in order to use the default loop. This value SHOULD NOT be given unless you're sure you want to explicitly use a given event loop instance.

If no $timeout argument is given and the promise stays pending, then this will potentially wait/block forever until the promise is settled. To avoid this, API authors creating promises are expected to provide means to configure a timeout for the promise instead. For more details, see also the timeout() function.

If the deprecated $timeout argument is given and the promise is still pending once the timeout triggers, this will cancel() the promise and throw a TimeoutException. This implies that if you pass a really small (or negative) value, it will still start a timer and will thus trigger at the earliest possible time in the future.

Note that this function will assume control over the event loop. Internally, it will actually run() the loop until the promise settles and then calls stop() to terminate execution of the loop. This means this function is more suited for short-lived promise executions when using promise-based APIs is not feasible. For long-running applications, using promise-based APIs by leveraging chained then() calls is usually preferable.

awaitAny()

The awaitAny(PromiseInterface[] $promises, ?LoopInterface $loop = null, ?float $timeout = null): mixed function can be used to wait for ANY of the given promises to be fulfilled.

$promises = array(
    $promise1,
    $promise2
);

$firstResult = Clue\React\Block\awaitAny($promises);

echo 'First result: ' . $firstResult;

See also the examples.

This function will only return after ANY of the given $promises has been fulfilled or will throw when ALL of them have been rejected. In the meantime, the event loop will run any events attached to the same loop.

Once ANY promise is fulfilled, this function will return whatever this promise resolved to and will try to cancel() all remaining promises.

Once ALL promises reject, this function will fail and throw an UnderflowException. Likewise, this will throw if an empty array of $promises is passed.

This function takes an optional LoopInterface|null $loop parameter that can be used to pass the event loop instance to use. You can use a null value here in order to use the default loop. This value SHOULD NOT be given unless you're sure you want to explicitly use a given event loop instance.

If no $timeout argument is given and ALL promises stay pending, then this will potentially wait/block forever until the promise is fulfilled. To avoid this, API authors creating promises are expected to provide means to configure a timeout for the promise instead. For more details, see also the timeout() function.

If the deprecated $timeout argument is given and ANY promises are still pending once the timeout triggers, this will cancel() all pending promises and throw a TimeoutException. This implies that if you pass a really small (or negative) value, it will still start a timer and will thus trigger at the earliest possible time in the future.

Note that this function will assume control over the event loop. Internally, it will actually run() the loop until the promise settles and then calls stop() to terminate execution of the loop. This means this function is more suited for short-lived promise executions when using promise-based APIs is not feasible. For long-running applications, using promise-based APIs by leveraging chained then() calls is usually preferable.

awaitAll()

The awaitAll(PromiseInterface[] $promises, ?LoopInterface $loop = null, ?float $timeout = null): mixed[] function can be used to wait for ALL of the given promises to be fulfilled.

$promises = array(
    $promise1,
    $promise2
);

$allResults = Clue\React\Block\awaitAll($promises);

echo 'First promise resolved with: ' . $allResults[0];

See also the examples.

This function will only return after ALL of the given $promises have been fulfilled or will throw when ANY of them have been rejected. In the meantime, the event loop will run any events attached to the same loop.

Once ALL promises are fulfilled, this will return an array with whatever each promise resolves to. Array keys will be left intact, i.e. they can be used to correlate the return array to the promises passed. Likewise, this will return an empty array if an empty array of $promises is passed.

Once ANY promise rejects, this will try to cancel() all remaining promises and throw an Exception. If the promise did not reject with an Exception, then this function will throw an UnexpectedValueException instead.

This function takes an optional LoopInterface|null $loop parameter that can be used to pass the event loop instance to use. You can use a null value here in order to use the default loop. This value SHOULD NOT be given unless you're sure you want to explicitly use a given event loop instance.

If no $timeout argument is given and ANY promises stay pending, then this will potentially wait/block forever until the promise is fulfilled. To avoid this, API authors creating promises are expected to provide means to configure a timeout for the promise instead. For more details, see also the timeout() function.

If the deprecated $timeout argument is given and ANY promises are still pending once the timeout triggers, this will cancel() all pending promises and throw a TimeoutException. This implies that if you pass a really small (or negative) value, it will still start a timer and will thus trigger at the earliest possible time in the future.

Note that this function will assume control over the event loop. Internally, it will actually run() the loop until the promise settles and then calls stop() to terminate execution of the loop. This means this function is more suited for short-lived promise executions when using promise-based APIs is not feasible. For long-running applications, using promise-based APIs by leveraging chained then() calls is usually preferable.

Install

The recommended way to install this library is through Composer. New to Composer?

This project follows SemVer. This will install the latest supported version:

$ composer require clue/block-react:^1.5

See also the CHANGELOG for details about version upgrades.

This project aims to run on any platform and thus does not require any PHP extensions and supports running on legacy PHP 5.3 through current PHP 8+ and HHVM. It's highly recommended to use the latest supported PHP version for this project.

Tests

To run the test suite, you first need to clone this repo and then install all dependencies through Composer:

$ composer install

To run the test suite, go to the project root and run:

$ vendor/bin/phpunit

License

This project is released under the permissive MIT license.

Did you know that I offer custom development services and issuing invoices for sponsorships of releases and for contributions? Contact me (@clue) for details.

Comments
  • Problem with ExtEventLoop (event)

    Problem with ExtEventLoop (event)

    use Psr\Http\Message\ServerRequestInterface;
    use React\Http\Response;
    use React\Promise\Promise;
    use function \Clue\React\Block\await;
    
    require_once 'vendor/autoload.php';
    
    $loop = new \React\EventLoop\ExtEventLoop;
    //$loop = new \React\EventLoop\StreamSelectLoop;
    //$loop = \React\EventLoop\Factory::create();
    
    echo 'Loop lib: ' . get_class($loop) . PHP_EOL;
    
    $server = new \React\Http\Server(function (ServerRequestInterface $request) use ($loop) {
        $promise = new Promise(function (callable $resolve) use ($loop) {
            $loop->addTimer(10, function () use ($resolve) {
                $resolve('async done');
            });
        });
    
        $result = await($promise, $loop);
        return new Response(200, ['Content-Type' => 'text/plain'], $result);
    });
    
    $socket = new \React\Socket\Server(8080, $loop);
    $server->listen($socket);
    
    $loop->run();
    
    

    Warning: EventBase::loop(): event_base_loop: reentrant invocation. Only one event_base_loop can run on each event_base at once. in /Users/alex/www/alex/php-crop-service/vendor/react/event-loop/src/ExtEventLoop.php on line 204

    It dont work on ExtEventLoop, only StreamSelectLoop.

    Do you have idea how fix it?

    question 
    opened by alexpts 14
  • infinite  loop

    infinite loop

    hello ,

    I use guzzle library , react promise , block react. my problem is that the system loops infinitely when I call as following

           $loop = React\EventLoop\Factory::create();
            $requestPromise = $this->sendMessageTravelportApi($requestXml, $endpoint);
            $responseXml = Clue\React\Block\await($requestPromise, $loop);
    

    the requestPromise as following:

     $requestDeferred = new React\Promise\Deferred();
            $requestParams = new Request("POST", $endpoint, $header, $message);
            $client = new Client();
            $client->sendAsync($requestParams)->then(
                    function (ResponseInterface $res) use($requestDeferred) {
                // $res->getStatusCode() . "\n";
                $requestDeferred->resolve($res->getBody()->getContents());
            }, function (RequestException $e) use($requestDeferred) {
                $requestDeferred->reject();
            });
            return $requestDeferred->promise();
    

    So I cant find why system loops infinitely.

    question 
    opened by yonus 14
  • Add optional timeout parameter to await*() methods

    Add optional timeout parameter to await*() methods

    Calling await*() with no timeout is scary. I think that in almost all cases, when we wait for something we don't want to potentially wait forever. While clients of this library could handle this themselves, it's much easier to add it to this library directly.

    Regarding the implementation: it might make sense to have a TimeoutException class to make it easier for clients to differentiate between rejected promises and timeouts.

    It's totally cool if you don't want to merge this!

    new feature 
    opened by joshdifabio 11
  • Check if the function is declared before declaring it.

    Check if the function is declared before declaring it.

    In case you use pthreads or something else related to threading you might encounter this issue. It happens only with functions and is fixable only by adding these checks. Another way to avoid this is to wrap functions as static into classes.

    bug new feature easy pick 
    opened by NikoGrano 8
  • Breaking main React loop

    Breaking main React loop

    Hi,

    I have a following use case:

    I'm using php-pm for request-response flow with psr7-adapter. So, my main class (application) is invoked with PSR7 request and response objects as any other middleware. An expected return value for middleware must be an instance of PSR7-Response. Since I'm using React HTTP client to call some APIs in my app I'm forced to use php-block-react so the PSR7-Response will be returned after all promises are done and data from APIs will be placed in PSR7-Response mentioned above. In simple words:

    1. I receive PSR7-Request
    2. I run few promises to call external APIs
    3. I set await function to wait for all promises and block returning empty PSR7-Response
    4. I parse promises response and fill my PSR7-Response with proper data
    5. I return ready PSR7-Response object

    I hope all here is clear and now my issue ;)

    await function calls $loop->run() internally for obvious reasons. After all conditions for await functions are meet (promises fulfilled), the $loop->stop() is called (I also understand why it must be done like that). So, after await function my main React loop is turned off and my whole application is shutted down, since there is now way to turn React loop on again. Below I post simple example (different code, but the same principle):

    {
      "name": "vendor_name/package_name",
      "description": "description_text",
      "minimum-stability": "stable",
      "license": "proprietary",
      "authors": [
        {
          "name": "author's name",
          "email": "[email protected]"
        }
      ],
      "require": {
        "clue/block-react": "^1.1.0"
      }
    }
    
    <?php
    
    require_once 'vendor/autoload.php';
    
    $loop = \React\EventLoop\Factory::create();
    
    // postpone await, so main loop can be started
    $loop->addTimer(0.5, function () use ($loop) {
        $promise = \React\Promise\Timer\resolve(6, $loop);
        $promise = $promise->then(function() {
            echo 'timer promise done' . PHP_EOL;
        });
    
        echo 'await loop start' . PHP_EOL;
        \Clue\React\Block\await($promise, $loop);
        echo 'await loop end' . PHP_EOL;
    });
    
    $loop->addPeriodicTimer(1, function() {
        echo 'test' . time() . PHP_EOL;
    });
    
    echo 'main loop start' . PHP_EOL;
    $loop->run();
    echo 'main loop end' . PHP_EOL;
    

    I resolved this by creating second, internal React loop to handle every new request. By this I gain possibility to shutdown only internal loop (not the whole app), but in the time of processing request (and all external API calls), my main React loop is blocked, so obviously not a great, final solution :/

    Any help is appreciated, maybe I'm doing something totally wrong here :/ Maybe I'm doing all right, this library is also totally correct, but the problem lies in absence of $loop->resume() function which will set $loop->running = true as stop() method sets it to false.

    question 
    opened by maciejmrozinski 7
  • Allow waiting inside a loop by ticking instead of running the loop

    Allow waiting inside a loop by ticking instead of running the loop

    I needed to wait for a promise while already within a loop. Because the await() function calls $loop->stop(), the loop I was already in stopped.

    I removed $loop->stop() and instead of $loop->run() I now call $loop->tick(). This has resolved my problem. The unittests are still working as well.

    Please let me know about any problems with this approach, I will try to resolve them.

    opened by JurJean 7
  • I fail to get it to work with reactphp-curl

    I fail to get it to work with reactphp-curl

    Hi there,

    i have a bunch of curl calls that i want to finish before i process further to save memory while processing a lot of data. But somehow block halts everything for infinite time, so nothing happens anymore.

    Even with trying it in a simple testcase with one curl request and awaitOne didn't work.

    I am not sure if that is a issue because of as mistake on my part or if reactphp-curl is incompatible with block. I would be gratefull if you could help me to work this issue out.

    Best regards and have a nice day.

    question 
    opened by Reilaen 7
  • Loop stops

    Loop stops

    Shortly after using any of the functions (await, awaitAll, even sleep) the app stops. It simply finishes when the current stack is done. If I remove the \Block function and replace it with a dummy, it works just fine. Even when I don't remove it, it works as expected, the promise resolves successfully and it's returned properly. But when the loop goes to the end, it stops, I presume because of the loop->stop() part in the source.

    Am I doing something wrong? Any suggestions would be appreciated.

    "react/event-loop": "^1.1" "clue/block-react": "^1.3"

    PHP 7.2.24-0ubuntu0.19.04.1 (cli) (built: Oct 24 2019 11:49:39) ( NTS )

    question 
    opened by BitBargain 6
  • Busy Loop Discussion

    Busy Loop Discussion

    Currently block relies on a while call to check if a flag has changed in order to implement async blocking. This may result in a busy loop wasting CPU cycles.

    There are alternatives to doing this. One can use a flock and block on the lock, this makes use of the OS locking mechanism to prevent busy looping. Another way is to use one of the process control extensions: http://php.net/manual/en/refs.fileprocess.process.php

    While the above 2 work. The former needs a lock file (which is not always readily available), the latter requires installing extensions which is not always available.

    A third way is to use http://php.net/manual/en/function.stream-select.php however this ideally should be paired up with the unix pipe call. But there doesn't seem to be a PHP wrapper for the anonymous pipe call, a discussion was formed here: https://bugs.php.net/bug.php?id=60896

    However an alternative is real sockets which is provided by native PHP: http://php.net/manual/en/function.socket-create-pair.php and http://php.net/manual/en/function.socket-select.php

    So combining the 2 together, we can create a non-busy loop for the async to sync conversion.

    opened by CMCDragonkai 5
  • How to use await inside a class function?

    How to use await inside a class function?

    I'm having some difficulty using Block\await function in reactphp codes. I implemented this issue in 3 ways but either way it failed to do my task!

    Number 1

    It will execute correctly but it close the connection and stops server

    public function awaitLottieResizer($amount, $asset)
        {
            try {
                $fun =  aPromiseFunction(); // it will return PromiseInterface
                return await($fun);
            } catch (\Exception $e) {
                return "Exception";
            }
        }
    

    Number 2

    It won't return anything and code stuck but the server is running

    public function awaitLottieResizer($amount, $asset)
        {
            try {
                $fun =  aPromiseFunction(); // it will return PromiseInterface
                return await($fun, null);
            } catch (\Exception $e) {
                return "Exception";
            }
        }
    

    Number 3

    It won't return anything and code stuck but the server is running

    public function awaitLottieResizer($amount, $asset)
        {
            try {
                $fun =  aPromiseFunction(); // it will return PromiseInterface
                return await($fun, React\EventLoop\Loop::get());
            } catch (\Exception $e) {
                return "Exception";
            }
        }
    
    question 
    opened by Parsoolak 4
  • Added small tip on Block\sleep behavior

    Added small tip on Block\sleep behavior

    Block\sleep usage can be a little bit confusing, so the loop is not blocked, but it is your program execution. In terms of non-blocking architecture, what I understand of an sleep is a Promise resolved after N seconds, From the developer POV, is nice to have this warning here.

    maintenance 
    opened by mmoreram 4
  • Heads up! Development focus on react/async

    Heads up! Development focus on react/async

    If you're currently using this project, you may want to check out the successor https://github.com/reactphp/async instead 🎉 We've merged the await() function from this project into the new react/async package without the optional parameters $loop and $timeout. Upgrading should still be simple and should take no longer than a few minutes in most cases:

    // old
    $result = Clue\React\Block\await($promise);
    
    // new
    $result = React\Async\await($promise);
    

    This project may see some smaller adjustments / fixes in the future, but all development efforts and new features will focus on react/async instead. Upgrading is highly recommended.

    We're planning to soft-deprecate this project in the future after a reasonable transition period. We want to ensure a smooth upgrade path and will not break any existing implementations, so you can keep installing old versions from this project, but should not expect any major changes and feature additions.

    Head over to https://github.com/reactphp/async!

    Refs: https://github.com/reactphp/async/pull/8 This ticket is similar to https://github.com/clue/reactphp-buzz/issues/177 by @clue.

    maintenance 
    opened by SimonFrings 0
Releases(v1.5.0)
  • v1.5.0(Oct 20, 2021)

    • Feature: Simplify usage by supporting new default loop. (#60 by @clue)

      // old (still supported)
      Clue\React\Block\await($promise, $loop);
      Clue\React\Block\awaitAny($promises, $loop);
      Clue\React\Block\awaitAll($promises, $loop);
      
      // new (using default loop)
      Clue\React\Block\await($promise);
      Clue\React\Block\awaitAny($promises);
      Clue\React\Block\awaitAll($promises);
      
    • Feature: Added support for upcoming react/promise v3. (#61 by @davidcole1340 and @SimonFrings)

    • Improve error reporting by appending previous message for Throwables. (#57 by @clue)

    • Deprecate $timeout argument for await*() functions. (#59 by @clue)

      // deprecated
      Clue\React\Block\await($promise, $loop, $timeout);
      Clue\React\Block\awaitAny($promises, $loop, $timeout);
      Clue\React\Block\awaitAll($promises, $loop, $timeout);
      
      // still supported
      Clue\React\Block\await($promise, $loop);
      Clue\React\Block\awaitAny($promises, $loop);
      Clue\React\Block\awaitAll($promises, $loop);
      
    • Improve API documentation. (#58 and #63 by @clue and #55 by @PaulRotmann)

    • Improve test suite and use GitHub actions for continuous integration (CI). (#54 by @SimonFrings)

    Source code(tar.gz)
    Source code(zip)
  • v1.4.0(Aug 21, 2020)

    • Improve API documentation, update README and add examples. (#45 by @clue and #51 by @SimonFrings)

    • Improve test suite and add .gitattributes to exclude dev files from exports. Prepare PHP 8 support, update to PHPUnit 9, run tests on PHP 7.4 and simplify test matrix. (#46, #47 and #50 by @SimonFrings)

    Source code(tar.gz)
    Source code(zip)
  • v1.3.1(Apr 9, 2019)

    • Fix: Fix getting the type of unexpected rejection reason when not rejecting with an Exception. (#42 by @Furgas and @clue)

    • Fix: Check if the function is declared before declaring it. (#39 by @Niko9911)

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Jun 14, 2018)

    • Feature: Improve memory consumption by cleaning up garbage references. (#35 by @clue)

    • Fix minor documentation typos. (#28 by @seregazhuk)

    • Improve test suite by locking Travis distro so new defaults will not break the build, support PHPUnit 6 and update Travis config to also test against PHP 7.2. (#30 by @clue, #31 by @carusogabriel and #32 by @andreybolonin)

    • Update project homepage. (#34 by @clue)

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Aug 3, 2017)

    • Feature / Fix: Forward compatibility with future EventLoop v1.0 and v0.5 and cap small timeout values for legacy EventLoop (#26 by @clue)

      // now works across all versions
      Block\sleep(0.000001, $loop);
      
    • Feature / Fix: Throw UnexpectedValueException if Promise gets rejected with non-Exception (#27 by @clue)

      // now throws an UnexceptedValueException
      Block\await(Promise\reject(false), $loop);
      
    • First class support for legacy PHP 5.3 through PHP 7.1 and HHVM (#24 and #25 by @clue)

    • Improve testsuite by adding PHPUnit to require-dev and Fix HHVM build for now again and ignore future HHVM build errors (#23 and #24 by @clue)

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Mar 9, 2016)

    • Feature: Add optional timeout parameter to all await*() functions (#17 by @clue)
    • Feature: Cancellation is now supported across all PHP versions (#16 by @clue)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Nov 13, 2015)

    • First stable release, now following SemVer
    • Improved documentation

    Contains no other changes, so it's actually fully compatible with the v0.3.0 release.

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Jul 9, 2015)

    • BC break: Use functional API approach instead of pseudo-OOP. All existing methods are now exposed as simple functions. (#13)

      // old
      $blocker = new Block\Blocker($loop);
      $result = $blocker->await($promise);
      
      // new
      $result = Block\await($promise, $loop);
      
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Jul 5, 2015)

  • v0.1.1(Apr 5, 2015)

    • run() the loop instead of making it tick(). This results in significant performance improvements (less resource utilization) by avoiding busy waiting (#1)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Apr 4, 2015)

Owner
Christian Lück
@reactphp maintainer / Freelance Software Engineer, all things web, passionate about coaching others building awesome things… Reach out if you need help
Christian Lück
Xr - Lightweight debug server utility built on ReactPHP.

XR ?? Subscribe to the newsletter to don't miss any update regarding Chevere. XR is a dump server utility built on top of ReactPHP. Features ✨ Dump si

Chevere 195 Dec 17, 2022
Pagekit is a modular and lightweight CMS built with Symfony components and Vue.js.

Pagekit Pagekit is a modular and lightweight CMS built with Symfony components and Vue.js. Homepage - Learn more about Pagekit Documentation - User an

Pagekit 5.5k Dec 30, 2022
This library brought ReactPHP and QueryList together

ReactPHP QueryList This library brought ReactPHP and QueryList together. Installation composer require ahmard/reactphp-querylist Usage Playing with Q

Ahmad Mustapha 5 Nov 19, 2021
This repository demonstrates exemplary implementation of chat using HTTP and Websocket servers in PHP using Kraken Framework components.

This repository demonstrates exemplary implementation of chat using HTTP and Websocket servers in PHP using Kraken Framework components.

Kraken 48 Aug 11, 2021
Enables developers to modify Magento installations (configuration, data) based on the given environment using n98-magerun.

Enables developers to modify Magento installations (configuration, data) based on the given environment using n98-magerun.

LimeSoda Interactive Marketing GmbH 73 Apr 1, 2022
A simple library to increase the power of your environment variables.

Environment A simple library (with all methods covered by php unit tests) to increase the power of your environment variables, contribute with this pr

João Paulo Cercal 56 Feb 8, 2022
A research raw data repository for researchers of Arba Minch University built using Codeigniter which follows MVC architecture. The front-end is build using Bootstrap.

Arba Minch University Dataset Repository This system is a research dataset repository for Arba Minch University researchers and is build using Codeign

Wuletaw Wonte 8 Jul 1, 2022
A lightweight framework-agnostic library in pure PHP for part-of-speech tagging

N-ai php pos tagger A lightweight framework-agnostic library in pure PHP for part-of-speech tagging. Can be used for chatbots, personal assistants, ke

Giorgio Rey 8 Nov 8, 2022
A lightweight SQL generation library.

Atlas A lightweight SQL builder library without any query execution or database connection requirements. The primary goals of this package are: To pro

RebelCode 1 May 11, 2022
Workshop environment for Decoupled Drupal

Decoupled Drupal Workshop ?? Welcome to the Bluehorn Digital Decoupled Drupal workshop repository! This repository contains a decoupled ready Drupal b

Bluehorn Digital 6 Feb 2, 2022
MajorDoMo is an open-source DIY smarthome automation platform aimed to be used in multi-protocol and multi-services environment.

MajorDoMo (Major Domestic Module) is an open-source DIY smarthome automation platform aimed to be used in multi-protocol and multi-services environment. It is based on web-technologies stack and ready to be delivered to any modern device. It is very flexible in configuration with OOP paradigm used to set up automation rules and scripts. This platform can be installed on almost any personal computer running Windows or Linux OS.

Sergei Jeihala 369 Dec 30, 2022
🐘 A probe program for PHP environment (一款精美的 PHP 探針, 又名X探針、劉海探針)

Simplified Chinese | 简体中文 Traditional Chinese(Taiwan) | 正體中文(臺灣) Traditional Chinese(Hong Kong) | 正體中文(香港) Japanese | 日本語 ?? X Prober This is a probe

Km.Van 1.2k Dec 28, 2022
Full PHP development environment for Docker.

Full PHP development environment based on Docker. Use Docker First - Learn About It Later! Join Us Awesome People Laradock is an MIT-licensed open sou

laradock 11.7k Jan 7, 2023
The Phar Installation and Verification Environment (PHIVE)

The Phar Installation and Verification Environment (PHIVE) Installation and verification of phar distributed PHP applications has never been this easy

null 509 Dec 29, 2022
A Magento Development Environment Made of Docker Containers

Docker for Magento 1 Extension Development Tl;dr How do I use this? Clone it. Type docker-compose up -d. Install a Magento Mount your file share. Deve

Michael A. Smith 99 May 10, 2021
A simple shell script which loads a magento environment

A simple shell script to load up a Magento environment and execute PHP code Very experimental and should only be ran on dev servers REQUIRES php pcntl

beeplogic 28 Feb 4, 2022
A dockerized magento 2 community environment ready for development or production.

Painless Magento 2 & 1 A dockerized magento 2 community environment ready for development or production. It supports magento 1.9.x for development Ins

Cocoa Web Studio 10 Apr 23, 2022
Mage2click toolset to create and manage the Magento Docker development environment with mutagen.io file-sync for macOS and native filesystem mounts on Linux.

Mage2click - Magento Docker Toolset Mage2click toolset is a system-wide command-line tool for creating and managing simultaneously running Magento Doc

Mage2click 69 Nov 28, 2022
This a php environment for developers. based on Vagrant & CentOS & laravel/homestead

Centstead 这是一个 PHP 调试环境 , 基于 centos,laravel/homestead. 介绍   基于开发的实际需求,PHP开发者通常需要一个贴近生产环境,又易于维护的测试与开发环境.以往的选择: xampp, wamp, phpstudy… 集成环境,启动方便,占用小,但是需

JasonChang 52 Sep 30, 2022