Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ext Openswoole Laravel Package

upscale/ext-openswoole

Connects Laravel Upscale to the OpenSwoole PHP extension, enabling coroutine-based HTTP serving, task workers, and runtime hooks for high-concurrency Laravel applications. A focused adapter for teams running OpenSwoole-powered Laravel services and workers.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a compatibility shim: it makes code written against ext-swoole's Swoole\* classes run on ext-openswoole (and vice-versa where possible), so you can use one extension in production and keep dependencies/app code untouched.

  1. Confirm what's actually installed — the wrapper cannot polyfill the extension itself:
    php -m | grep -i swoole
    php -r 'echo SWOOLE_VERSION, PHP_EOL;'
    
  2. Install:
    composer require upscale/ext-openswoole
    
  3. Verify aliases are registered. Check the package's composer.json for an autoload.files bootstrap — that file must be what registers the aliases, and it must be a hard require, not require-dev:
    php -r 'var_dump(class_exists("Swoole\\Coroutine"), class_exists("OpenSwoole\\Coroutine"));'
    
  4. First use case: you're running Laravel Octane (or a coroutine worker) on ext-openswoole, but your app code or a third-party package references Swoole\Http\Server, Swoole\Coroutine::getCid(), Swoole\Timer, etc. Add the package, run as usual — the Swoole\* names now resolve to the OpenSwoole implementation.

Look first at the package's src//bootstrap file (the alias map is the whole product) and its README. If the map is short, it's worth reading end-to-end before trusting it in production.

Implementation Patterns

Write new code against the Swoole\* namespace, not OpenSwoole\*. That's the namespace the wrapper aliases, so your code stays portable between the two extensions.

Octane integration. Start workers with the OpenSwoole driver and let the shim cover the gaps:

php artisan octane:install --server=openswoole
php artisan octane:start --server=openswoole

Custom middleware or a custom ServerFactory that calls Swoole\Coroutine::getCid() or Swoole\Timer::after() keeps working without edits.

Wrap the runtime behind one small service rather than sprinkling extension calls through the app — this gives you a single place to mock in tests and to swap extensions:

final class CoroutineRunner
{
    public function run(callable $fn): mixed
    {
        return \Swoole\Coroutine\run($fn);
    }

    public function id(): int
    {
        return \Swoole\Coroutine::getCid();
    }
}

Bind it in a service provider; assert on it in feature tests instead of touching the extension.

CI matrix. Test the same code against both extensions — this is where the wrapper pays off:

strategy:
  matrix:
    ext: [swoole, openswoole]
steps:
  - run: |
      if [ "${{ matrix.ext }}" = "openswoole" ]; then pecl install openswoole; else pecl install swoole; fi
  - run: composer install && php artisan test

Packages you publish. Put upscale/ext-openswoole in require (not suggest) and code against Swoole\*; consumers on either extension get a working install. If you can't take the dependency, at minimum suggest it and document the assumption.

Feature detection only. Use extension_loaded('openswoole') / extension_loaded('swoole') to branch on capabilities, never to choose a class name.

Gotchas and Tips

  • Never load both extensions in one SAPI. Duplicate/conflicting symbols, undefined behavior. Enforce it in the Dockerfile and CI, not just in docs.
  • Aliasing is shallow. Classes get aliased; constants, legacy swoole_* functions, and behavioral differences (Runtime::enableCoroutine hook flags, signal handling, coroutine scheduling nuances) are not normalized. Test the specific features you rely on.
  • get_class() returns the canonical OpenSwoole name after aliasing. Don't branch on it — use instanceof \Swoole\Coroutine.
  • Serialization drift. Queued jobs, cached payloads, and anything storing class names will differ across environments. Keep extension classes out of DTOs.
  • Version skew is real. OpenSwoole 22.x/23.x and Swoole 5.x have diverged. Pin the package and the extension, and treat extension upgrades as breaking-change events with an integration test run.
  • Ordering matters. Aliases must be registered before any Swoole\* reference — Composer files autoload handles this; a class_alias() in a service provider's register() is too late for pre-boot code (custom Octane server factory, preload scripts).
  • Debug the map:
    print_r(array_values(array_filter(
        get_declared_classes(),
        fn ($c) => str_starts_with($c, 'Swoole\\') || str_starts_with($c, 'OpenSwoole\\')
    )));
    
  • After toggling extensions, clear Octane's cached server file (php artisan octane:install --server=... regenerates it) and fully restart workers — stale workers will hold old symbol tables.
  • Maturity risk. With 2 stars and 0 dependents, treat this as an audit-and-pin dependency. The package is essentially a class_alias list; if it's small, vendoring it as bootstrap/swoole-compat.php removes a supply-chain hop and gives you control over which classes are mapped.
  • Opcache preload: if you preload Swoole\* classes, ensure the alias bootstrap runs during preload compilation, or preload the OpenSwoole\* names instead.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle