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

Eval Command Laravel Package

wp-cli/eval-command

Run arbitrary PHP code or files from the command line with WP-CLI. wp eval executes a code string, while wp eval-file loads a PHP file with positional arguments. Both support --skip-wordpress to run without WordPress and --hook to run after a specific WordPress hook fires.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

The first thing to correct at intake: this is not a Laravel package. wp-cli/eval-command is a WP-CLI bundled command that adds wp eval and wp eval-file to the WordPress CLI. It has no Laravel service provider, no facade, no config surface, and nothing to autoload into a Laravel application. Framing it as a "Laravel/PHP package" will produce the wrong adoption decision.

Where it actually fits our estate:

  • If we run any WordPress (marketing site, headless CMS backend, WooCommerce store), this command is already installed on every box that has WP-CLI. Zero integration cost.
  • If we run Laravel alongside WordPress (Laravel app consuming WP REST or the WP database, content sync jobs, WooCommerce order ingestion), wp eval-file is a viable escape hatch for one-off data operations and incident triage — invoked as a subprocess from an Artisan command, never as a Composer dependency.
  • It is not a replacement for artisan tinker, Laravel migrations, seeders, or scheduled jobs. It is not a migration tool, not idempotent, and not transactional.

The execution model is the key architectural fact: code is evaluated inside a method, so globals must be explicitly globalized. Since v2.2.7 $args is available as a global for eval-file; since v2.2.9 $assoc_args is available in eval. Since v2.2.8 --hook=<hook> defers execution until a named WordPress hook fires, which is the only reliable way to reach code paths that depend on wp_loaded or later lifecycle state. --skip-wordpress skips the WordPress bootstrap entirely — that mode is effectively plain PHP and is the only variant I would consider safe in a Laravel-only context.

Integration feasibility

Low coupling, but also low leverage. Concretely:

  • Distribution: bundled with WP-CLI; the repo install path (wp package install) exists only to override the bundled version. That means version management is really WP-CLI version management, not Composer dependency management. Our upgrade lever is "which WP-CLI release is on this host," which is usually baked into a Docker image or a global binary — frequently unowned.
  • Runtime: requires PHP 7.2.24+ at minimum; the v2.2.10 line requires wp-cli/wp-cli v2.13. Modern Laravel hosts on PHP 8.1+ are fine on the PHP side, but the WP-CLI binary itself must be current enough to match.
  • Namespace/scope: evaluated code lands in global scope with WordPress fully bootstrapped — all plugins and the theme are loaded. In a hybrid Laravel/WP setup there is no shared autoloader, so any Laravel class referenced from wp eval will fatal. This is a hard boundary, not a configuration detail.
  • Output contract: results go to stdout as raw text. There is no --format=json envelope on eval/eval-file; if an engineer echos inside the script and we also echo a JSON payload, we get corrupt output. Any automation must own its output discipline explicitly.

Technical risk

  • Arbitrary code execution is the entire product. There is no sandbox, no allowlist, no dry-run, no capability check beyond whatever shell access the operator already has. On a production host with database credentials in wp-config.php, wp eval is equivalent to root-adjacent database access. This is a governance problem before it is a technical one.
  • No transactionality. A script that fails halfway leaves partial writes. Recent hardening in v3.0.1 ("harden eval-file against failures while preparing the file") addresses file preparation, not mid-execution rollback. We must assume no atomicity.
  • Plugin side effects at bootstrap. Loading WordPress loads every active plugin. Anything hooked to init/wp_loaded that sends mail, fires webhooks, or purges caches will run. --skip-wordpress avoids this but also removes the WordPress APIs, which is usually why we're there.
  • Silent no-ops. --hook=<hook> on a hook that never fires yields a successful exit code and zero work. Easy to misread in a runbook.
  • Secret exposure. Inline PHP in a shell command lands in bash history, ps output, CI logs, and shell audit trails. eval-file - reading from STDIN is the mitigation, and it should be the default in our standards.
  • Adoption signal is misleading. 10 stars and 0 dependents looks like abandonment, but as a bundled WP-CLI component the dependents metric is structurally invisible. Conversely, do not read the repo's release metadata (which shows a forward-dated release) as a maturity guarantee — pin and verify the WP-CLI version actually running in our images rather than trusting the feed.
  • License: MIT, unencumbered, no procurement friction.

Key questions

  1. Do we operate WordPress anywhere in the estate? If no, this is a non-decision and we stop here.
  2. Who owns the WP-CLI binary version in our base images, and what is the upgrade cadence? That is the real versioning control point.
  3. Is wp eval currently permitted on production hosts, and by whom? If nobody knows, we have an unmonitored arbitrary-code-execution path today.
  4. Can we get shell/host audit logging around wp invocations, or do we need to proxy it through a controlled runner?
  5. Are there recurring operations currently done via ad-hoc wp eval that should be promoted to a proper wp scaffold package command with tests?
  6. For our hybrid cases, can the boundary be "Laravel orchestrates, WP executes" — Laravel never shares a process with WordPress?

Integration Approach

Stack fit

Treat this as operational tooling, not a dependency. There is nothing to add to composer.json in a Laravel service. The integration surfaces are:

Scenario Fit Approach
Laravel-only app None Do not adopt; use artisan tinker / migrations
WordPress-only site Strong Already installed; define usage policy and runbooks
Laravel orchestrating WordPress (content/order sync) Moderate Laravel Artisan command shells out to wp eval-file - with script on STDIN
Laravel plugin inside WordPress Weak Do not use eval to reach Laravel; use a proper WP-CLI command package

The third row is the only genuinely interesting hybrid pattern, and it should be constrained: the Laravel command owns idempotency, batching, logging, and exit-code interpretation; WordPress just executes a narrow, versioned script.

Migration path

  1. Inventory first. Grep CI configs, cron entries, deploy scripts, and team runbooks for wp eval. In my experience most organizations have more of these than anyone expects, and they are undocumented tribal knowledge.
  2. Classify each hit: one-off debugging (keep, but move behind runbook), recurring operational task (promote to a tested WP-CLI command package), or data migration (rewrite as an explicit, versioned script with a rollback plan).
  3. Consolidate scripts into a versioned repo rather than living in shell history. wp eval-file with a path in a checked-out repo is auditable; wp eval '...' inline is not.
  4. Standardize on STDIN for anything containing credentials or environment-specific values.
  5. Retire inline wp eval from production as the end state; retain eval-file against versioned scripts with an approval gate.

Compatibility

  • Pin against the WP-CLI version in our images, and assert a minimum in CI. Version skew between dev machines (Homebrew WP-CLI) and containers is the most common source of "works locally, fails on deploy."
  • PHP floor of 7.2.24 is not a constraint for us, but confirm before assuming any legacy host is in scope.
  • --hook requires ≥2.2.8; --use-include requires ≥2.2.0; $assoc_args in eval requires ≥2.2.9. If scripts rely on these flags, that sets an effective WP-CLI floor that must be enforced, not assumed.
  • --use-include vs default eval changes __FILE__/__DIR__ behavior. WP-CLI rewrites magic constants, but the semantics differ between the two modes and scripts that depend on relative paths will break when someone flips the flag. Pick one convention per script and document it.

Sequencing

  1. Weeks 1–2 — Inventory and policy draft. Establish that wp eval is arbitrary code execution and classify it accordingly in our access-control model. No code changes.
  2. Weeks 2–4 — Pilot in local + staging only. Convert two or three recurring manual operations to versioned eval-file scripts with STDIN and explicit exit codes. Validate exit-code behavior under fatal errors and under a non-firing --hook, since both matter for CI gating.
  3. Weeks 4–6 — CI integration for read-only smoke checks (e.g., assert a plugin option exists, assert content counts). Read-only only.
  4. Weeks 6–8 — Production read-only access via a controlled runner with audit logging. Write access remains human-gated and out of automation.
  5. Ongoing — Promote anything executed more than twice a quarter into a purpose-built WP-CLI command package with Behat coverage. This is the exit criterion that prevents eval-script sprawl.

Operational Impact

Maintenance

Genuinely low, and that is the package's main virtue. It is bundled with WP-CLI, so maintenance collapses into "keep WP-CLI current," which we should be doing regardless for security patches. The package itself has a narrow surface — two commands, five flags — and a steady but unremarkable release history (mostly CI, PHPCS, and PHP-version housekeeping, with functional changes like --hook, --use-include, and $args/$assoc_args exposure arriving incrementally). Expect it to track WP-CLI releases rather than drive its own roadmap.

The real maintenance burden is the scripts we write with it, not the package. Ungoverned, this becomes a shadow codebase of untested, unversioned PHP living in shell history and Confluence pages. Budget for curation.

Support

Community-supported under the WP-CLI project. GitHub issues accept bugs and PRs; general support is explicitly redirected to the WP-CLI handbook and WordPress forums. There is no vendor SLA. That is fine for an ops tool and unacceptable as a dependency in a revenue-critical path — which reinforces the "tooling, not dependency" framing.

Internal support model should be: a named owner for the WP-CLI binary, a documented runbook per approved script, and a review requirement for new production scripts.

Scaling

Poorly suited to high-frequency or high-volume work, and this should be stated plainly rather than discovered. Each invocation pays full WordPress bootstrap — loading core, all plugins, and the theme — typically hundreds of milliseconds to several seconds before a single line of our code runs. It is a per-invocation CLI process with no daemon, no connection pooling, and no batching primitive. Using it in a loop over thousands of records is an anti-pattern; batch inside one script, or build a proper command.

Horizontal scale is a non-issue (it's a CLI process), but concurrency is: two operators running write scripts against the same database have no coordination mechanism, no locking, and no visibility into each other.

Failure modes

Failure Symptom Mitigation
Fatal error mid-script Partial writes, non-zero exit, truncated stdout Idempotent scripts; explicit pre-flight checks; backups before writes
--hook never fires Exit 0, no work done Assert a sentinel was reached; validate hook name against target WP version
Plugin bootstrap side effects Emails sent, webhooks fired, caches purged --skip-wordpress where possible; test in staging first
Global scope collision Variables clobbered, unexpected behavior Explicit global; unique variable prefixes
Stdout pollution Corrupt JSON for downstream consumers Enforce "no bare echo" convention; separate logging channel
Secret leakage Credentials in history/CI logs Standardize on eval-file - via STDIN
Version skew Works locally, fails in container Pin WP-CLI in images; assert version in CI
Unbounded runtime Hung process holding DB connections timeout wrapper; memory limit awareness

The dangerous failure mode is the quiet one: exit code 0, no error, wrong or incomplete state. Automation gating on wp eval must never trust exit code alone — every production script needs a verification step that re-reads the result.

Ramp-up

Low for competent PHP developers — an hour to be productive, because the mental model is just "PHP with WordPress loaded." The friction is in the non-obvious semantics, and those deserve explicit documentation rather than discovery:

  • Code runs in a method, so globals must be declared.
  • __FILE__/__DIR__ are rewritten; behavior differs between eval and --use-include.
  • --skip-wordpress removes the WordPress APIs that usually motivated the call.
  • Output is bare stdout; there is no structured envelope.
  • No rollback.

New engineers should be given a template script and a rule: if you run it twice, it becomes a command package. That single norm prevents the sprawl that otherwise makes this tool an audit finding rather than an accelerant.

Recommendation: adopt as sanctioned operational tooling on WordPress hosts with a written usage policy and a controlled production runner; do not add to any Laravel application's dependency graph; treat every recurring script as a candidate for promotion into a tested WP-CLI command.

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.
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support