toro/server-bundle
Symfony bundle that integrates the Toro PHP server runtime into your application, registering its services in the DI container and exposing configuration plus console commands for starting, stopping, and monitoring background workers from the familiar Symfony toolchain.
Assume from the start that this is a legacy integration: the bundle targets Symfony2 (PHP 5.x era) and pins a ReactPHP-based toro server. Before writing any code, check three things in the repo:
composer.json — the symfony/symfony range, the toro/toro (or equivalent runtime) version it pulls, and the PHP constraint. If it requires ~2.3/~2.7 and PHP >=5.4, budget for a fork before it will install alongside anything modern.DependencyInjection/ToroServerExtension.php and the bundle class — confirm the service alias and parameter prefix (typically toro_server.*). That is your extension point for everything else.Command/ — the console command that boots the server. That command is your real entry point; the bundle is mostly a thin wrapper around it.Minimal wiring:
// app/AppKernel.php
$bundles = [
// ...
new Toro\Bundle\ServerBundle\ToroServerBundle(),
];
# app/config/config.yml
toro_server:
host: 127.0.0.1
port: 8080
# worker count / document root keys vary by version — read the Extension class
First use case to validate the install: run the bundle's server command in the foreground against your existing app.php front controller, confirm it binds and serves one request, and confirm the process handles a second request without restarting. If it cannot serve request #2, nothing downstream matters.
You will not find meaningful documentation at 0 stars — treat README.md, the test suite (if any), and the Extension class as the specification.
Treat the server command as the integration point, not the bundle. The bundle's job is to register a console command and a small set of DI services. Everything real happens in the worker loop, which you control through the command.
Wrap the front controller, don't rewrite it. The typical pattern is to point the server at a small bootstrap script that dispatches through the Symfony kernel, so your existing routing, security, and controllers are unchanged:
// bin/toro-app.php
require __DIR__.'/../app/autoload.php';
$kernel = new AppKernel(getenv('APP_ENV') ?: 'prod', false);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
Scope services for long-running workers. Anything holding per-request state (a request-scoped logger, a session, a user token, a Doctrine EntityManager) must be reset between requests or marked non-shared. A common pattern is a small "resetter" service called from the worker loop:
foreach ($this->resetters as $resetter) {
$resetter->reset(); // clear EM, detach handlers, reset locale/user
}
Separate the "dev server" and "production worker" use cases. For dev, run the command in the foreground with a watcher and short worker lifetime so code changes reload. For production, define it as a supervised process (systemd unit or supervisord), one process per CPU, with an explicit worker count.
Integration with the container: register your own compiler pass if you want to auto-collect resetters — tag services toro.resetter, collect in process(), inject the array into the worker loop. This is the only clean extension point the bundle realistically offers.
If the bundle is unmaintained, vendor the pattern. Because the surface is small, the pragmatic long-term move is to lift the command into your own AppBundle and drop the dependency, keeping your config keys identical so migration is a no-op for the rest of the app.
EntityManager ($em->clear(), $em->getConnection()->close()) every N requests.Request::createFromGlobals() is wrong in a worker. It reads $_SERVER/$_GET once. Bind per-connection and construct the Request from the actual socket data, or the second request will silently reuse the first.$_SESSION, $_SERVER, and any static caches in your code carry over. Explicitly reinitialize per request or you get cross-user data bleed — a security issue, not just a bug.session_start() semantics differ per request cycle.dump(). In a forked/worker model var_dump goes to the server's stdout, not the HTTP response. Prefer Monolog with a rotating handler and a distinct channel for the worker.Configuration.php in the bundle — do not trust the README, and definitely do not trust blog posts for a package this obscure.$? and wire it into your supervisor's restart policy.composer audit / roave/security-advisories and pin everything.symfony/web-server-bundle for dev and a real web server (nginx + php-fpm) for production.How can I help you explore Laravel packages today?