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

Shell Command Laravel Package

wp-cli/shell-command

WP-CLI Shell Command adds an interactive PHP REPL to WP-CLI, letting you explore and run code against a WordPress install from the command line. It bootstraps WordPress and gives quick access to its APIs for debugging, inspection, and experimentation.

Deep Wiki
Context7

Getting Started

wp-cli/shell-command is not a Composer library you pull into composer.json — it's a WP-CLI package that registers a single command, wp shell, which drops you into an interactive PHP REPL (PsySH) with WordPress fully bootstrapped: $wpdb, WP_Query, hooks, all active plugins, and your theme functions are already in scope.

Treat it as the WordPress equivalent of php artisan tinker. If you're maintaining a WordPress install alongside a Laravel app — or running a hybrid setup like Bedrock, or a Laravel app with a wordpress/ subdirectory — this is the fastest way to poke at WP state without writing throwaway scripts.

Install and confirm (global, per user, not per project):

wp package install wp-cli/shell-command
wp package list          # verify it's there
wp help shell            # flags vary by release; always check

First use case — verify what's actually loaded and reachable:

wp shell --url=example.test
>>> get_option('blogname')
=> "Example Site"
>>> $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type='product'")
=> "1284"
>>> get_posts(['post_type' => 'page', 'numberposts' => 3])

Note --url= — in a multisite or a multi-vhost machine this decides which site boots. Getting this wrong is the source of most "why is my data empty" confusion.

Implementation Patterns

REPL for inspection, wp eval for anything repeatable. As soon as code becomes a two-liner you want again tomorrow, move it to wp eval-file scripts/foo.php. The shell is for exploration; eval-file is for repeatability, and it survives in git.

wp eval-file tools/backfill-meta.php --url=example.test

Preload your own helpers. Rather than retyping helper closures, keep a bootstrap file and pull it in:

wp shell --require=dev/shell-bootstrap.php
// dev/shell-bootstrap.php
function order_summary(int $id): array {
    $order = wc_get_order($id);
    return ['total' => $order->get_total(), 'status' => $order->get_status()];
}

Piped / non-interactive mode for CI and containers. Where there's no TTY, feed statements on STDIN — handy for smoke-testing a deploy:

echo 'echo get_option("home");' | wp shell --url=example.test

Combine with WP-CLI aliases for remote environments (wp @staging shell), but only where the alias uses SSH and the remote allocates a TTY. Interactive REPLs over aliases are fragile; for staging debugging prefer wp @staging eval-file.

Hybrid Laravel + WordPress. If WordPress lives inside a Laravel tree, boot Laravel from the shell rather than the other way around — the WP-CLI bootstrap already owns the process:

>>> require __DIR__ . '/vendor/autoload.php';
>>> $app = require __DIR__ . '/bootstrap/app.php';
>>> $kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
>>> $kernel->bootstrap();
>>> app('db')->connection()->table('users')->count();

Expect autoloader collisions if both sides pin different versions of the same package (Guzzle, Symfony polyfills). If it blows up, do the inverse: php artisan tinker and require the WP bootstrap inside it.

PsySH features are the real time-saver. dump($thing) gives colored, collapsed output instead of a wall of var_dump; doc($fn) prints signatures; ls $object lists methods; trace shows the last exception's trace. Learn these three and you'll stop reaching for error_log.

Gotchas and Tips

  • A fatal error kills the session. exit(), a wp_die(), or a type error in evaluated code terminates the REPL and you lose all variables. Wrap risky calls in try { } catch (\Throwable $e) {} — and note that wp_die inside AJAX context will hard-exit regardless.
  • Everything is booted. All plugins and the theme load, so wp shell is slow on a plugin-heavy site and can be broken by a plugin that echoes output on plugins_loaded and corrupts the prompt. Use the global --skip-plugins / --skip-themes flags to bisect — that's often faster than Xdebug.
  • Multisite context is sticky. switch_to_blog(5) inside the session works, but $wpdb->prefix and cached options don't fully reset. Start a fresh session with --url= rather than switching mid-session for anything involving writes.
  • Memory grows. Long REPL sessions accumulate object references (especially WP_Query results and WooCommerce orders). If you see Allowed memory size exhausted, restart before assuming a code bug.
  • Package installs fail for boring Composer reasons. wp package install shells out to Composer into ~/.wp-cli/packages/; version conflicts with an old global Composer, or WP_CLI_PHP_ARGS='-d memory_limit=512M', are the usual culprits. Fix with wp package update or reinstall after clearing ~/.wp-cli/packages.
  • PsySH history lives at ~/.config/psysh/psysh_history. Useful for recovering a lost one-liner; a permissions bug there silently disables up-arrow history. ~/.config/psysh/config.php is the extension point for startup banners and custom commands.
  • Never wire wp shell into automation or expose it. It executes arbitrary PHP with full DB credentials. It's a local developer tool; in production, reach for wp eval under an explicit, reviewed script.
  • Don't mistake it for a debugger. It's excellent for "what is the value of this option," poor for "why is this hook firing twice." For the latter, Xdebug plus wp --debug (WP-CLI's own global flag) beats sprinkling dump().
  • Pin the version per environment. The package updates independently of WP-CLI core; wp package list showing different versions across a team's machines produces "works on my machine" REPL behavior, especially around --require handling.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core