wp-cli/export-command
Export your WordPress site's content to a WXR file from the command line. This WP-CLI package adds the wp export command for generating WordPress eXtended RSS exports of posts, pages, and more—ideal for migrations, backups, and moving content between sites.
What the package actually is. wp-cli/export-command is not a general-purpose PHP library — it is a WP-CLI command bundle. It registers the wp export subcommand and depends on a bootstrapped WordPress runtime (WP_Query, wpdb, post type/taxonomy registries, pluggable functions). There is no public PHP API, no service provider, no PSR-compatible interface, and no events. Its only contract is: exit code, stdout, and a WXR file on disk.
Architecture fit. Poor for a pure Laravel application; reasonable for a hybrid WordPress + Laravel estate. The only viable integration shapes are:
wp export via Symfony\Process from a scheduled command or queued job.composer.json of a Laravel app and attempting to call it in-process. It will pull wp-cli/wp-cli and a pinned symfony/console, which conflicts with Laravel's console component and offers no benefit.Integration feasibility. Low-to-moderate effort if a WordPress runtime already exists and we own it. The command surface is straightforward and well-suited to automation (--post_type, --status, --author, --category, --start_date, --end_date, --dir, --filename). If there is no WordPress runtime in the target environment, this package is not integrable — the work becomes "stand up WordPress," which is a different project.
Technical risk.
symfony/console constraints versus Laravel. Mitigate by installing WP-CLI as a PHAR, not a Composer dependency.wp export has historically shipped inside WP-CLI core. Loading this package alongside a modern WP-CLI can raise "command already defined" or shadow the built-in implementation — load order and version pinning must be verified in a spike.content:encoded are the classic re-import corruption points.Key questions for the team.
--url per site).Stack fit. PHP 7.4+/8.x, Composer-installable, MIT. Best consumed as a runtime tool inside a WordPress container image, not as an application dependency of the Laravel codebase. Recommended shape:
app (Laravel) --Process--> wp-cli container --writes--> shared volume (WXR)
\-- queued ingest job reads WXR from shared volume / S3
Migration path. None for existing Laravel data — WXR is WordPress-native. The real migration work is the WXR → Eloquent mapping layer:
| WXR element | Laravel target |
|---|---|
item (wp:post_type) |
Per-type model or single polymorphic Content model |
wp:post_id, wp:post_name |
Natural/legacy key for idempotent upserts |
category / wp:term |
Pivot tables, slug-keyed |
wp:postmeta |
JSON column; must maybe_unserialize PHP-serialized values |
content:encoded |
Sanitized HTML (CDATA unwrap) |
wp:attachment_url |
Media sync job (separate from this package) |
Compatibility.
wp export is already bundled before loading this package.WP_CLI constant guards often short-circuit plugin logic — audit for this).max_execution_time on the exporter host.Sequencing.
wp post list --format=count.wp:post_id, dead-letter handling.--start_date watermark stored per site; daily or hourly cadence depending on freshness requirement.Maintenance. Small code surface, MIT license, WP-CLI org stewardship — but only 13 stars signals near-zero independent adoption. The command is effectively maintained as part of WP-CLI core, so version drift is the primary maintenance concern, not feature churn. The stated last release of 2026-08-04 should be treated as unverified metadata and confirmed against Packagist before planning. Budget ~1–2 days per WordPress minor upgrade for regression testing.
Support. Community-only: GitHub issues and WP-CLI Slack. No SLA, no vendor. We own the pipeline end-to-end, including patches. Bus factor is small; institutional knowledge must be documented rather than assumed.
Scaling characteristics.
--post_type × date window (e.g. monthly) to bound file size and enable parallel export of independent types.rsync/S3 sync is a hard dependency for any usable migration.Failure modes to instrument.
| Failure | Symptom | Mitigation |
|---|---|---|
| Unregistered CPT | Zero items for a type, exit 0 | Assert expected counts per post type post-run |
| Memory exhaustion | Fatal, exit 255, truncated file | Raise memory_limit, chunk, write to .tmp then rename |
| Timeout / mid-run kill | Partial WXR that still parses | Checksum + item count + <wp:wxr_version> trailer check |
Timezone drift on --start_date |
Missed or duplicated records | Explicit UTC watermarks; overlap windows and dedupe on ingest |
| Serialized meta corruption | Silent field loss on re-import | Unit tests on maybe_unserialize fixtures |
| Deletions | Stale content persists in target | Explicit reconciliation pass; WXR has no tombstone |
| Duplicate re-import | Duplicated rows | Upsert on wp:post_id; never blind-insert |
Ramp-up. Low for the exporter itself — anyone fluent in WP-CLI is productive in half a day. The asymmetrical cost is the consumer side: a robust WXR ingest in Laravel is 1–2 sprints including serialization quirks, media, and idempotency. Plan and staff accordingly; the package is the cheap half of the project.
Recommendation. Conditional adopt. Justified only when a WordPress runtime is already owned and the requirement is content egress from it. It is not a Laravel package, should not enter the Laravel composer.json, and should be treated as an external CLI tool with a thin, well-instrumented contract: run it, verify exit code + item counts + checksum, ingest the artifact.
How can I help you explore Laravel packages today?