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

Wp Cli Bundle Laravel Package

wp-cli/wp-cli-bundle

WP-CLI Bundle packages the WP-CLI command-line toolkit and its dependencies for managing WordPress installs from the terminal. Install via Composer to run plugin, theme, database, and core commands.

View on GitHub
Deep Wiki
Context7

Getting Started

WP-CLI is a PHP CLI for WordPress — not a Laravel package — but it lands in Laravel work more often than people expect: hybrid WP + Laravel apps, marketing sites on the same VPS, and one-off data migrations where the content lives in a WordPress database. The v2.12.0 release is a routine maintenance release; treat it as a compatibility checkpoint (bump the phar in CI, confirm it still runs on the same PHP minor your Laravel app uses) rather than a feature drop you need to plan around.

Minimal setup:

# phar install (recommended, keeps WP-CLI independent of your app's vendor dir)
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp

# or via Homebrew / apt / Composer (pick one — see Gotchas)
brew install wp-cli

wp --info          # confirms PHP binary, WP-CLI version, phar path
wp cli update      # self-update the phar

Where to look first:

  1. wp help and wp help <command> — the built-in docs are better than most web results.
  2. wp cli info — tells you which PHP binary and which config files are being loaded. This is the first thing to run when behaviour differs between your terminal and CI.
  3. wp-cli.yml in the WordPress document root — the project-level config that pins path, url, and default flags.

First real use case: a Laravel app that shares a server with a WordPress install, and you need to move content between them.

cd /var/www/blog
wp db export /tmp/blog-$(date +%F).sql --add-drop-table
wp search-replace 'https://old.example.com' 'https://new.example.com' --all-tables --dry-run

From Laravel, wrap it with the Process facade rather than exec() so you get exit codes and stderr:

use Illuminate\Support\Facades\Process;

$result = Process::path(config('wordpress.root'))
    ->timeout(120)
    ->run(['wp', 'option', 'get', 'home', '--skip-plugins', '--skip-themes']);

if ($result->failed()) {
    report(new \RuntimeException($result->errorOutput()));
}

Implementation Patterns

Per-project wp-cli.yml. Commit it next to wp-config.php so nobody has to remember --path and --url:

path: web/wp
url: https://blog.test
core install:
  admin_user: admin
  skip-email: true

Aliases for remote environments. In ~/.wp-cli/config.yml, define @staging and @prod with ssh: and path:. This turns destructive commands into something you can review before running:

@staging:
  ssh: [email protected]/var/www/blog
  url: https://staging.example.com

Then wp @staging plugin list --update=available is a safe read; anything with @prod should require a second pair of eyes.

Bootstrap-and-seed for local dev. Script the whole install so a fresh clone is one command, mirroring what php artisan migrate --seed gives you:

wp core download --locale=en_GB
wp config create --dbname=blog --dbuser=root --dbpass=secret --skip-check
wp core install --url=https://blog.test --title=Blog --admin_user=admin [email protected]
wp plugin activate --all
wp theme activate my-theme
wp rewrite structure '/%postname%/'

Custom commands as the Artisan analogue. WP-CLI's WP_CLI::add_command() is the direct counterpart to Artisan::command(), with the same mental model: a name, a handler, positional args, and associative flags. Put them in an mu-plugin so they load everywhere and are never deactivated by accident:

if (defined('WP_CLI') && WP_CLI) {
    WP_CLI::add_command('app sync-orders', function ($args, $assocArgs) {
        $dryRun = \WP_CLI\Utils\get_flag_value($assocArgs, 'dry-run', false);
        // ...
        WP_CLI::success($dryRun ? 'Dry run complete.' : 'Synced.');
    });
}

WP_CLI::log() for progress, WP_CLI::warning() for non-fatal issues, WP_CLI::error() (optionally with an exit code) to abort. That maps cleanly onto Artisan's info/warn/error.

Cross-app data sync. wp db export on the WordPress side, then import into a Laravel-managed staging DB or a read-only replica. For anything that touches post content, always --dry-run first, then --all-tables --precise (see Gotchas), and keep the pre-change dump.

Scheduled maintenance from the Laravel scheduler. If you already run php artisan schedule:run every minute, you don't need two cron systems:

$schedule->exec('wp cron event run --due-now --path=/var/www/blog')
    ->everyFiveMinutes()
    ->withoutOverlapping();

CI usage. wp core install --skip-email, wp plugin activate, wp cron event run --due-now, and wp eval-file tests/fixtures.php make a WordPress fixture reproducible. Pin the phar version in the image so a wp cli update in v2.12.x's line doesn't silently change behaviour mid-quarter.

wp eval / wp eval-file for throwaway work. For one-off inspection, this beats writing a debug plugin. Load a file with wp eval-file ./scripts/audit.php, or inline a query check with wp eval 'var_dump(get_option("home"));'.

Scaffolding for command packages. wp scaffold package my-org/my-command generates a Composer-installable command package with Behat tests — the right shape if you're distributing a command across several client sites.

Gotchas and Tips

Don't mix install methods. A phar on PATH plus wp-cli/wp-cli-bundle in a project's vendor/bin produces two different versions depending on cwd, and the failure mode is confusing ("this works in my terminal"). Pick phar for ops, Composer bundle for projects that need to unit-test custom commands. Run wp cli info to confirm which one executed.

Config precedence is flag > wp-cli.yml > ~/.wp-cli/config.yml > WP_CLI_CONFIG_PATH. When a --url seems to be ignored, it's almost always a wp-cli.yml in a parent directory being picked up. wp cli info prints the resolved config paths.

--path vs --url are not interchangeable. --path tells WP-CLI where WordPress lives; --url tells it which site in a multisite network. On multisite, omitting --url picks the network's primary site, and you'll wonder why the option you set didn't appear on the site you were looking at.

wp db reads credentials from wp-config.php, not your Laravel .env. If both apps share a database, they can drift. Prefer distinct databases, or generate wp-config.php from the same source of truth (wp config create takes --dbhost etc., so you can script it).

search-replace and serialized data. WP-CLI is serialization-aware, but a naive replace across --all-tables still corrupts page-builder meta and JSON-encoded blocks. Always --dry-run, take a dump, then use --precise for URL changes and --recurse-objects when object properties hold nested strings. Exclude noisy tables (--skip-tables=wp_posts) where a plugin owns its own URL rewriting.

Run as the correct user. Invoking wp as root creates root-owned files in wp-content/uploads and silently breaks uploads and plugin updates for the web user. sudo -u www-data wp ... is the fix, not chmod -R 777.

WP-CLI bootstraps WordPress fully. Plugin fatals and memory exhaustion from a heavy page builder will kill your CLI command. --skip-plugins, --skip-themes, and WP_CLI_PHP_ARGS=-d memory_limit=512M are your escape hatches — but note that skipping plugins changes what wp option get returns for options registered by those plugins.

Guard custom commands on WP_CLI. A WP_CLI::add_command() call in a regular plugin that loads under FPM will fatal on the undefined class. Hence the defined('WP_CLI') && WP_CLI wrapper, and mu-plugin rather than a normal plugin if it must always be available.

Exit codes matter when scripting. 0 success, 1 general error, 3... check the docs rather than assuming 1 for everything. In Laravel, Process::run()->failed() covers it, but don't swallow errorOutput() — WP-CLI puts the useful message there, not in stdout.

Remote aliases need non-interactive SSH. Key-based auth, no passphrase prompt, and WP_CLI_SSH_PRE_CMD if the remote needs an export PATH=... before wp resolves. Aliases also carry their own --url, so a local flag can be silently overridden by the alias definition.

Debugging: wp <cmd> --debug on the individual command, WP_CLI_DEBUG=1 for early bootstrap failures, and wp --info when the PHP binary is wrong (very common when a host has both php and php8.3 on PATH). For v2.12.0 specifically, re-run wp cli update and then smoke-test your custom commands — the extension API is stable but bootstrap and PHP-version handling is where the maintenance releases actually land.

Version pinning in CI. wp cli update mid-pipeline is a non-deterministic build. Download the phar at a fixed version in your Dockerfile and bump it deliberately, which is the only sane way to absorb a routine release like this one.

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.
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections