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

Webman Framework Laravel Package

workerman/webman-framework

Webman is a high-performance PHP framework built on Workerman for fast, scalable web apps and APIs. It supports HTTP, WebSocket, TCP, and other protocols, with simple routing, middleware, low overhead, and persistent memory.

View on GitHub
Deep Wiki
Context7

Getting Started

workerman/webman-framework is the core package, not the thing you normally install by hand. Day-to-day you get it transitively from the skeleton:

composer create-project workerman/webman myapp
cd myapp
php start.php start        # foreground, logs to stdout

Only add it explicitly when you are embedding webman into an existing Workerman/TCP project.

Read these first, in order:

  1. start.php — the bootstrap; every run/stop/reload command goes through it.
  2. public/index.php — thin HTTP entry.
  3. config/ — app.php, route.php, middleware.php, process.php, database.php, log.php.
  4. app/controller/IndexController.php — the generated hello-world.
  5. support/ — helpers (response(), json(), view(), config(), env()), the container, bootstrap.

First real use case — a JSON endpoint:

// config/route.php
use Webman\Route;
Route::get('/health', fn () => json(['ok' => true, 'ts' => time()]));

Route::post('/users', [app\controller\UserController::class, 'store']);
namespace app\controller;

use support\Request;

class UserController
{
    public function store(Request $request)
    {
        $data = $request->post();
        // ...
        return json(['id' => 1], 201);
    }
}
php start.php start
curl localhost:8787/health

If you edit a file you must php start.php reload (or run with php start.php start -d plus a watcher). There is no FPM-style per-request reload — this is the single biggest behavioral difference coming from Laravel.

Implementation Patterns

Controllers are resolved per request, but the process is not. Instantiate nothing at property level that holds request state.

Route organization. Keep config/route.php thin and split into route/*.php files as the app grows; webman loads them all. Controller auto-routing (app/controller/Foo/BarController::baz → /foo/bar/baz) is convenient but makes URLs implicit — prefer explicit routes for anything public.

Middleware is the main cross-cutting seam:

namespace app\middleware;

use Webman\MiddlewareInterface;
use Webman\Http\Response;
use support\Request;

class Auth implements MiddlewareInterface
{
    public function process(Request $request, callable $handler): Response
    {
        if (!$request->header('authorization')) {
            return json(['error' => 'unauthorized'], 401);
        }
        return $handler($request);   // must return the Response
    }
}

Register globally in config/middleware.php, per-route/group in config/route.php, or per-controller via annotations. Order is array order, outermost first.

Database. illuminate/database and Eloquent ship in the framework:

use support\Db;

$users = Db::table('users')->where('active', 1)->limit(20)->get();
Db::transaction(function () use ($data) { /* ... */ });

Models extend support\Model (or Illuminate\Database\Eloquent\Model). Configure pools/connections in config/database.php; under a coroutine runtime (swow/swoole) this is where you tune pool size.

Config and env. config('app.debug'), env('APP_ENV'), .env at project root. Config is loaded once at boot into memory — mutating config at runtime does not persist across workers and confuses everyone; use it read-only.

Background work. Long-running or scheduled jobs do not belong in a controller. Add custom processes in config/process.php (each gets its own worker loop with onWorkerStart), or use the webman/cron and webman/redis-queue plugins. This is where webman genuinely beats FPM: a resident process with a timer, no cron daemon juggling.

Plugins. composer require webman/redis etc.; plugin config lands in config/plugin/<vendor>/<name>/. webman/console gives you php webman make:controller User so you don't hand-write namespaces.

Deployment shape. Nginx (or Caddy) reverses / to 127.0.0.1:8787; static files served by Nginx from public/. Run under supervisor/systemd with php start.php start -d. Deploy = rsync code → composer install --no-dev → php start.php reload. reload is graceful and keeps in-flight requests alive; restart is not.

Testing. Unit-test services and domain code with PHPUnit normally; for HTTP-level tests, boot the app once and drive requests through the container rather than relying on $_SERVER/$_GET, which are not the source of truth here.

Gotchas and Tips

  • No auto-reload. Editing controllers, config, routes, or .env does nothing to the running process. php start.php reload after code/config changes. New or changed config/process.php entries need restart, not reload.
  • Memory is shared across requests within a worker. Static properties, $GLOBALS, and container singletons persist. A singleton that captures $request is a leak and a cross-request data bleed. Clear request-scoped caches in middleware try/finally.
  • Blocking calls serialize the worker. sleep(), heavy synchronous HTTP, big file reads inside a handler stall every request that worker would have served. Use async clients (workerman/http-client, Guzzle only if you accept the cost), or switch to a coroutine runtime if you need real concurrency.
  • exit / die kills the worker. The master respawns it, but in-flight requests are dropped. Throw exceptions and let the framework render the error page.
  • Superglobals are unreliable. $_GET, $_POST, $_SERVER, $_SESSION are not per-request state. Always use $request->get(), ->post(), ->header(), ->file(), ->session().
  • header(), setcookie(), session_start(), ob_start() do not apply. Return a Response: response()->withHeader(...), response()->cookie(...), $request->session()->set(...). Stray echo before returning a Response can corrupt output.
  • Log/permission traps. Daemon processes frequently end up as the wrong user after sudo; runtime/logs and runtime/session then fail silently-ish. Check php start.php status and the log dir ownership first when "nothing happens."
  • Session driver defaults to file. Multi-node or container deployments need the Redis driver in config/session.php; otherwise users bounce between nodes.
  • Windows has no pcntl/signals. start -d, reload, status are limited or absent. Use WSL/Docker so behavior matches production.
  • Version coupling. workerman/webman-framework and workerman/workerman must be upgraded together; a composer update that bumps only one is a classic boot failure. Pin both in composer.json.
  • Debug mode leaks. 'debug' => true in config/app.php gives stack traces — great locally, unacceptable in prod.
  • This repo is the engine, not the on-ramp. With ~148 stars and few dependents, docs, issues, and examples overwhelmingly live in walkor/webman and the webman documentation site. Searching this repository for "how do I…" answers will mostly waste time; search the parent project and the plugin ecosystem.
  • Extension points worth knowing: support\Container bindings for swapping implementations (repositories, mailers) in tests; config/middleware.php ordering for global behavior; config/process.php for anything long-running; events (Event::emit) for decoupling side effects from controllers.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource