wp-cli/eval-command
Adds WP-CLI commands to run arbitrary PHP code or execute PHP files from the command line. Supports running with or without loading WordPress, delaying execution until a specific hook, and passing args to scripts.
## Getting Started
### Minimal Steps
1. **Installation**: No additional installation required—bundled with WP-CLI (`wp --info` to verify).
2. **First Command**: Run inline PHP:
```bash
wp eval 'echo "Hello, WordPress!";'
wp eval-file /path/to/script.php
--hook for lifecycle-aware execution (e.g., wp eval 'var_dump($wpdb)' --hook=init).wp db or wp plugin commands for context.Debugging a Plugin Hook:
wp eval 'add_action("wp_loaded", function() { var_dump(current_user_can("administrator")); });' --hook=wp_loaded
Inline Code Execution:
wp eval 'echo ABSPATH;' --skip-wordpress).wp eval "$(jq -r '. | @sh' <<< '{"key": "value"}')"
File-Based Scripting:
.php files (e.g., scripts/cleanup.php).$args (accessible globally):
wp eval-file scripts/cleanup.php --skip-wordpress arg1 arg2
// scripts/cleanup.php
global $args;
echo "Args: " . implode(', ', $args);
Hook-Aware Execution:
wp eval-file tests/plugin_hook_test.php --hook=wp_loaded
Sandboxed Execution:
--skip-wordpress for isolated PHP (e.g., testing libraries):
wp eval 'require_once "vendor/autoload.php"; $obj = new \Some\Library();' --skip-wordpress
wp eval to interact with WordPress from Laravel’s Artisan:
php artisan tinker --execute='shell_exec("wp eval 'return get_option(\"home\");'")'
wp eval-file deploy/checks.php --hook=muplugins_loaded
wp eval debugging:
{
"wp eval": {
"prefix": "wpeval",
"body": "wp eval '${1:code}' --hook=${2:wp_loaded}"
}
}
Global Scope Quirks:
eval are not global by default.
wp eval '$x = 1; echo $x;' # Fails (undefined $x)
wp eval 'global $x; $x = 1; echo $x;'
File Paths in eval-file:
__FILE__/__DIR__ may resolve incorrectly in eval-file.--use-include or preprocess paths:
wp eval-file script.php --use-include
Hook Timing:
--hook may not fire if WordPress isn’t loaded.--skip-wordpress with caution; test hooks with wp eval first.STDIN Limitations:
wp eval-file - reads from STDIN but may strip shebangs.#!/usr/bin/env php):
cat script.php | wp eval-file -
Error Suppression:
wp eval 'trigger_error("Test");' 2>&1 | grep -A5 "Test"
Log Output:
wp eval 'error_log("Debug", 0);' --hook=shutdown
Check wp-content/debug.log.
Inspect WordPress State:
wp eval 'var_dump($GLOBALS["wp_filter"]);' --hook=all
Custom Hooks:
wp-cli/eval-command by adding your own --hook flags via WP-CLI’s command framework.Pre/Post-Execution:
wp-cli/wp-cli-tests to mock eval in unit tests:
$this->runCommand('eval', ['code' => 'return "test";']);
Security:
--skip-wordpress to trusted users (e.g., via wp user permissions).eval usage in wp-config.php:
add_action('wp_loaded', function() {
if (defined('WP_CLI') && WP_CLI) {
error_log("Eval executed: " . $_SERVER['argv'][1] ?? '');
}
});
php -v).wp cli update).--use-include for cross-platform file paths.wp shell:
wp shell "eval('return get_site_option(\"siteurl\");')"
wp eval-file --use-include <<< '<?php echo "Template: " . get_template();'
wp eval 'echo "Time: " . microtime(true);' --hook=init
```markdown
## Laravel-Specific Adaptations
### Bridging WP-CLI and Laravel
1. **Artisan Integration**:
- Create a custom Artisan command to proxy `wp eval`:
```php
// app/Console/Commands/WpEval.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class WpEval extends Command {
protected $signature = 'wp:eval {code}';
public function handle() {
$output = shell_exec("wp eval '{$this->argument('code')}')");
$this->info($output);
}
}
```
- Run via:
```bash
php artisan wp:eval 'echo ABSPATH;'
```
2. **Service Provider Hooks**:
- Dynamically load WordPress in Laravel’s bootstrap:
```php
// config/app.php
'providers' => [
App\Providers\WordPressServiceProvider::class,
],
```
```php
// app/Providers/WordPressServiceProvider.php
use Illuminate\Support\ServiceProvider;
class WordPressServiceProvider extends ServiceProvider {
public function boot() {
if ($this->app->runningInConsole()) {
$this->app->singleton('wp', function() {
return shell_exec('wp eval \'return get_bloginfo();\'');
});
}
}
}
```
3. **Queue Workers**:
- Offload `eval-file` to Laravel Queues:
```php
// app/Console/Commands/ProcessWpQueue.php
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Queue;
class ProcessWpQueue extends Command {
public function handle() {
Queue::push(new EvalJob('wp eval-file /path/to/script.php'));
}
}
```
### Debugging Laravel + WordPress
- **Shared Storage**:
- Use Laravel’s `storage/logs/laravel.log` and WordPress’s `debug.log` in tandem:
```bash
wp eval 'error_log("Laravel Debug", 0);' --hook=shutdown
```
- **Xdebug**:
- Configure `php.ini` for both stacks:
```ini
xdebug.mode=debug
xdebug.client_host=127.0.0.1
xdebug.idekey=LARAVEL
```
- Trigger via:
```bash
wp eval 'xdebug_break();' --hook=init
```
### Performance Considerations
- **Avoid `eval` in Loops**:
- Cache results in Laravel’s `cache()`:
```bash
wp eval '
How can I help you explore Laravel packages today?