mlo/console-bundle
mlo/console-bundle is a Laravel/PHP package that provides a lightweight console bundle for structuring and registering custom commands. It helps organize command logic, simplify CLI workflows, and integrate cleanly with existing Laravel applications.
What changed in v2.0.0. This release retargets the bundle at Symfony 5, drops Symfony 4 and below, and renames the command from console to tinker. That rename is the thing most likely to break you: any script, Makefile target, shell alias, or doc that calls bin/console console ... will now fail with "command not defined." Grep your repo for the old name before you upgrade.
Pin the right major for your Symfony version.
composer show mlo/console-bundle --all
composer require "mlo/console-bundle:^2.0"^1.0 (v2 will not install; its symfony/* constraints exclude you)The project is still very low-activity (tiny star count, essentially one maintainer release). v2 is a maintenance bump, not a revival — do not read it as a long-term support signal.
Register the bundle in config/bundles.php:
return [
// ...
MLO\ConsoleBundle\ConsoleBundle::class => ['dev' => true, 'test' => true],
];
Keep it out of prod unless you have a specific operational need — see the security note in Gotchas.
Confirm the command name in your installed version. The README may still reference the old name; the command list is the truth:
bin/console list | grep -i tinker
bin/console help tinker
If you upgraded and the grep returns nothing, you are either on v1 (look for console) or the bundle failed to load — run bin/console list -vvv to surface the reason.
First use case: call a service method without writing a throwaway command. Instead of scaffolding a one-off App\Command\DebugFooCommand, use tinker to fetch a service and invoke a method on it interactively. That is the day-to-day win: probing services, triggering a job, or clearing a cache during development without a code change and a deploy.
Interactive service probing (dev). Use tinker as a lightweight REPL for services: fetch a service by id, inspect what it returns, then call a specific method with arguments. This replaces the old habit of dumping var_dump($container->get(...)) into a controller and hitting a route.
Update your scripts during the upgrade. The v1→v2 rename is mechanical but easy to half-do. Sweep for it:
grep -rn "console console\|bin/console console" Makefile scripts/ docs/ .github/ 2>/dev/null
Then rewrite the invocation targets:
reindex:
bin/console tinker app.search.indexer reindex
Alias the old name if you have muscle memory or many docs. Symfony lets you register an alias on a command you control, but not directly on a third-party one. The cheap fix is a shell alias or a thin wrapper command in src/Command/ that extends the bundle's command and sets protected static $defaultName = 'console'; plus an alias to tinker. Do this only if the rename churn is genuinely large — otherwise just standardize on tinker and drop the shim.
Ad-hoc operational tasks. For a service that already encapsulates a task (a report generator, an importer, a cache warmer), wiring the call through tinker lets you run it from the CLI without a dedicated command class. Keep these invocations in a Makefile or shell script so they are reproducible rather than typed from memory.
Debugging the wiring itself. When a service behaves unexpectedly in one environment, fetch it from the CLI container via tinker and compare with what debug:container reports. This quickly distinguishes "wrong service configured" from "service broken."
Pair with Symfony's built-in debug:container. debug:container --show-private, debug:container <id>, and debug:autowiring are maintained and more capable for pure inspection. Use tinker only for the invocation part — fetching and calling — and lean on core commands for discovery. Do not duplicate debug:container functionality the framework already gives you better.
Wrap in your own Symfony command when it stabilizes. If "fetch service X, call method Y with these args" becomes routine, promote it to a real #[AsCommand] class and drop the bundle dependency. The bundle is best used as a discovery/debug tool that informs the commands you eventually keep — and given its release cadence, that promotion is the safest long-term move.
Test-environment use. Registering it in test lets integration tests invoke service methods through the console kernel, which is occasionally handy during debugging, though usually a direct self::getContainer()->get(...) in a test is cleaner. Note that the rename applies here too if you have test helpers shelling out to the old command.
console → tinker is the breaking change. v2 removes the old name rather than aliasing it (per the release notes). Upgrade failures are usually silent at install time and loud at runtime — Command "console" is not defined. Search CI configs, Docker entrypoints, cron files, and runbooks, not just src/.symfony/* constraints with composer show --all before assuming compatibility — "Symfony 5" in a release note often means the 5.x line current at the time of writing, not every 5.x patch.$container->get($id), it throws ServiceNotFoundException for anything not explicitly public: true. Make services public narrowly:
services:
App\Search\Indexer:
public: true
Remember Symfony may remove unused private services at compile time — mark them public or reference them to keep them alive.dev/test, or gate it behind an environment check and an explicit allowlist if you must run it in prod.tinker is a collision-prone name. Other REPL/debug packages (and future framework tooling) can register the same name, and in a multi-bundle app the winner depends on registration order. If bin/console tinker behaves unlike the bundle's docs describe, run bin/console list and bin/console help tinker to check you are hitting this command and not another.debug:container already exists; if the bundle ships a similarly named command, prefer the core one to avoid surprise behavior differences between Symfony versions.-vvv to see the underlying exception. Common causes: wrong service id (use debug:autowiring), private service, a service requiring request-scoped context that fails outside HTTP, or an old script still calling console instead of tinker.composer update, and re-run your grep for the old command name after every major bump.How can I help you explore Laravel packages today?