Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/jgalea/swapline/archive/refs/heads/main.zipNo built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.
Swapline
Swapline is a free WordPress plugin for search and replace across database tables, with safe handling of serialized data and JSON.
What it does
- Search and replace across the tables you pick, with table sizes, select-all and core-only shortcuts.
- Serialized values are rebuilt with correct byte lengths at any depth, including serialized strings inside serialized strings. Objects are never instantiated (
allowed_classes => false). - JSON values are matched in their escaped form (
https:\/\/…,é) and must still decode after the change. - Broken serialized values are left alone and counted.
- Case-insensitive and regex modes, dry runs, and a side-by-side diff of every changed cell for the last five runs.
- Unlimited saved profiles.
- Batched AJAX processing with a progress bar. Tables without a primary key are supported.
- Multisite: network admin only, tables from every site.
- Backups of the whole database or selected tables to a gzipped SQL file, written in batches with a progress bar. A search and replace can be applied to the backup file only, which leaves the live site alone and gives you a file to import on a new domain.
- Backups are kept in a randomly named folder under uploads, closed to the web by
.htaccess,web.configand random file names, and downloaded through a nonce- and capability-checked handler. A retention setting keeps the latest backups. - A live search and replace can back up the selected tables first.
- Import a
.sqlor.sql.gzupload, or one of your backups, with an optional search and replace on the imported data. Every statement is checked before anything runs: onlyCREATE TABLE,DROP TABLE,INSERT ... VALUESwith literal values,LOCK/UNLOCK TABLESand sessionSETare accepted. Tables load under temporary names and are swapped in with oneRENAME TABLE, so a failed import leaves the live database as it was. - Importing can keep you logged in and keep the site's
siteurlandhome. wp swapline run <search> <replace> [<table>...] [--dry-run] [--regex] [--case-insensitive] [--profile=<name>] [--backup].wp swapline backup [<table>...] [--search=<search> --replace=<replace>]andwp swapline import <file> [--search=<search> --replace=<replace>] [--keep-url].
The screen is under Tools > Search & Replace, or Settings > Search & Replace in the network admin.
Requirements
- WordPress 6.2 or later
- PHP 8.0 or later
Development
composer install
vendor/bin/phpunit
vendor/bin/phpcs
SWAPLINE_NAIVE_ENGINE=1 vendor/bin/phpunit runs the suite against a bare str_replace, and every test should fail. SWAPLINE_NAIVE_SPLITTER=1 vendor/bin/phpunit --filter SplitterTest does the same for the SQL splitter with explode(';').
Extending
swapline_admin_tabsfilters the admin tabs (slug => [label, render]).swapline_before_runandswapline_after_runfire around every run, from the admin and WP-CLI.swapline_excluded_tables,swapline_history_sizeandswapline_max_recorded_changesadjust what's listed and kept.swapline_step_secondssets how long each backup or import request works before handing back to the browser.swapline_enqueue_assetsfires when the admin screen loads its scripts.
License
GPLv2 or later.