laminas/laminas-cli
laminas-cli provides a Symfony Console-based command runner for Laminas and Mezzio applications, letting you register CLI commands as services and execute them through a unified laminas-cli binary.
bin/laminas runner that reads a laminas-cli.commands config map and resolves each command through a PSR-11 container. The decision it informs is whether to hand-roll command registration/discovery or take a ~50-line dependency. For a Laminas MVC or Mezzio codebase, buying wins; there is nothing proprietary here to build.acme/ops-commands) and register them in every Laminas/Mezzio app with one config entry and factory mapping. That supports a "shared internal tooling library" roadmap item cheaply.Adopt when all of these hold:
laminas-servicemanager or equivalent), so command dependencies can be injected rather than constructed.--container=<path> escape hatch to boot an alternate container (useful for CI, cron, or multi-tenant deployments).Look elsewhere when:
symfony/framework-bundle's console application already does container-backed command discovery; this adds a duplicate abstraction.To executives: This is small, free (BSD-3), and boring in the right way — a connector that lets our existing Laminas/Mezzio applications expose operational commands (data fixes, imports, warmers, cron jobs) through one consistent entrypoint instead of scattered shell scripts. It removes duplicated credentials and config from ops scripts and gives us a reusable internal tooling library across apps. The honest caveat: it is niche, low-adoption glue with a thin maintainer base, so we adopt it only where we already run Laminas/Mezzio — and if our stack is Laravel, we should not adopt it at all, because Laravel's Artisan already covers this and more. Cost is roughly a day of engineering to register our first commands; ongoing cost is a Composer bump per PHP/Symfony major.
To engineering: One composer require, one laminas-cli.commands config key mapping vendor:command names to command classes, and a factory per command in service_manager (MVC) or dependencies (Mezzio). Commands are plain symfony/console commands, so they're portable and testable in isolation; since 1.15 you can use Console attributes instead of the config map. Constraints to plan around: pinned to PHP 8.2+ and symfony/console 7–8, no scheduling layer (we own cron/Supervisor), and it is a runner only — do not let it grow into a home for business logic. Treat it as replaceable infrastructure: keep command classes free of package-specific APIs so a future move to Artisan or a standalone Symfony console app is a mechanical port, not a rewrite.
How can I help you explore Laravel packages today?