Database Search and Replace Script in PHP

Search Replace DB version 3.1.0 allows you to carry out database wide search/replace actions that don’t damage PHP serialized strings or objects with a user friendly interface and experience.

Installation & Use

search-replace-mobile-screenshot Now acts like a web app!

Please read all instructions and familiarise yourself with the risks of using this tool first, downloading of this tool signifies your acceptance of the risks and problems associated with the script.

To use the script, download the zip file from below, extract the folder called search-replace-db-master (assuming you are using the 3.1.0 version), renaming it to something secret of your choosing, upload it via FTP, SFTP or SCP to your web server’s public facing directory, then navigate to that folder in your browser. The script will automatically attempt to find and populate the database field but you must check that the details are correct and that it is for the database you wish to carry out a search/replace operation on.

A typical WP install with this script would have the folders as follows:


IMPORTANT: Do not place the contents of the script’s folder into your root directory! It isn’t designed or supposed to run from there and, if you use the auto-delete functionality, it will delete everything in that folder, which could wipe out your site. I can’t stress this enough. If this isn’t clear for you it would be a good idea to seek expert help – hire a developer for an hour or two to come and do this for you.

To see how you can use this tool to aid migrations, check out our article on WordPress migrations or visit the WP Tuts+ article that mentions this script.

If you are in any doubt whatsoever about how to use this standalone script, then please consider getting an expert in. It’s a really powerful bit of code that if used badly can damage a WP install beyond repair. If you want help, get in somebody like us, for example, or any of the other great guys listed over at CodePoet.

IMPORTANT: This code is supplied with no warranty or support implied. You use it entirely at your own risk. The code is licensed under the GPL V3 and you should be aware of its limitations and how they affect you and your use of this code. Please also read the instructions and warnings provided and always take a verified backup of your database before starting.

Download v 3.1.0

Older server? Try v 2.1.0


Please beware of adverts that offer a download button!

Why is there an ad here? Because the small amount of revenue this advert might bring us helps to go towards the not inconsiderable cost of running the search/replace project. It’s in the order of thousands of pounds, believe it or not, and we’re working to a new version with better compatibility and this will help.


Test 20160504:
* Version 3.1.0 (Web UI and CLI versions) tested against PHP 7.0.6 and functioned correctly.
* Version 2.1.0 confirmed to not work with PHP 7.0.6 but is kept for use on older servers.

Version 3.1.0:
* Safety checks to prevent deletion when installed incorrectly. However, you should still take care when dealing with files on your server.
* JavaScript popup confirmation on ‘Delete Me’.
* Port number option in both the GUI and CLI. Use –port nnn to set a non-default MySQL port.
* Fixed Drupal bootstrap behaviour. Start up of script uses Drupal data as guide, no longer relies on a full successful Drupal initialisation before script will allow you to proceed.
* Driver selection improved so that PDO will be attempted first if PDO+mysql is available, with mysqli being used as a fallback. This fixes ‘driver not found’ errors.
* Removed mysql_ functions and replaced with mysqli_.
* Improved JS preview overlay for dry runs. This means that the right pane will always show the most accurate data possible. If serialised strings are present, highlights are not displayed.

Version 3.0.0:
* Major overhaul
* Multibyte string replacements
* UI completely redesigned
* Removed all links from script until ‘delete’ has been clicked to avoid security risk from our access logs
* Search replace functionality moved to it’s own separate class
* Replacements done table by table to avoid timeouts
* Convert tables to InnoDB
* Convert tables to utf8_unicode_ci
* Use PDO if available
* Preview/view changes
* Optionally use preg_replace()
* Scripts bootstraps WordPress/Drupal to avoid issues with unknown serialised objects/classes
* Added marketing stuff to deleted screen (sorry but we’re running a business!)

Version 2.2.0 (never formally released but patched into v3.0.0):
* Added remove script patch from David Anderson (
* Added ability to replace strings with nothing
* Copy changes
* Added code to recursive_unserialize_replace to deal with objects not just arrays. This was submitted by Tina Matter.
* ToDo: Test object handling. Not sure how it will cope with object in the db created with classes that don’t exist in anything but the base PHP.

For changes prior to v2.2.0 please refer to index.php where you will find a complete changelog. You can also browse the project on github.

To Be Done

Ensure UTF8 encoding is enforced (see comments). Added in v2.1.0
Self deletion or security system to prevent accidental security risks. Added in v3.0.0
Release CLI version for use on non-WP sites, or for other purposes (already supports use on any MySQL DB.) Added in v3.0.0
Change to GPL V3. Added in v3.0.0
Eliminate warnings and remove deprecated function calls. Added in v2.1.0
Add facility to subscribe to interconnect/it Newsletter. Added in v3.0.0
Confirm deletion has actually happened.
Add old versions for download to this page.


We’d love to get contributions, bug reports and more on the Search Replace DB public github repository. Please come on over – you’ll be more than welcome!


We’ve been asked a lot in the comments box below about accepting donations. But you can’t believe what a headache that is from an accounting and tax perspective.

Consequently all we can say is that if you wish to you can buy a personal gift for the key developers from one of the wishlists below – especially given that it’s a spare time project. If others who have contributed wish to provide us their wishlist links then we’d be more than happy to add them.

David Coveney is the project lead.
James Whitehead added the nice UI in v2.0+.
Robert O’Rourke created version 3.0.0 with its AJAX UI and massive improvements.

  • Rahul 22 / Oct / 2016 at 5:04 pm

    We really love this tool ! One click and all entries are changed easily.

    We appreciate your hard work interconnectit team !

  • Weby 20 / Oct / 2016 at 8:41 pm

    ¡EXCELENTE! Una magnífica herramienta que me ayudó a solucionar el problema que tenía un cliente por una base de datos con urls diferentes. Son unos cracks! Muchas gracias. Saludos desde México

  • Ramesh 17 / Oct / 2016 at 11:52 am

    it working great. thanks for the tool

  • Pingwiny 13 / Oct / 2016 at 2:15 pm

    I like this one and use it very often.

  • 2046 8 / Oct / 2016 at 11:53 am

    it rocks!

  • Sentimientos 7 / Oct / 2016 at 9:59 am

    Thanks!!!! 🙂

  • patricia 5 / Oct / 2016 at 6:11 pm

    This is the best way to change files routes when you move your wp site, thank you very much!

  • diamond sharma 26 / Sep / 2016 at 10:46 am

    thanks alot for this script.
    Helped me change all my domain url easily. Had been pulling my hairs to do this task but this tool made it so simple
    thanks again and you are awesome bro

  • Michael A. Echague 22 / Sep / 2016 at 7:25 am

    This work for me! thank you.

  • Michele 21 / Sep / 2016 at 2:32 pm

    I’ve been using your script for many years but I never thought of dropping a line to let you know you are awesome. So here you go:


    Grazie mille!

  • ANDRES WATSON 9 / Sep / 2016 at 8:52 pm

    GREAT TOOL! I tried to use the 3.1 version in an Azure environment and it shows an AJAX error, I tried with the 3.0 and worked perfectly. Any idea?

    • David Coveney
      David Coveney 12 / Sep / 2016 at 3:28 pm

      Occasionally people do experience AJAX errors – we suspect mostly it’s a time out but sometimes there are messages in the system log hinting at this.

      What happens if you do one table at a time?

  • Chris 9 / Sep / 2016 at 4:04 pm

    Awesome script!
    I had to move a wordpress installation with domain-change. The script did exactly what to do and everything works after the search-and-replace.

    Thank’s a lot.

  • Michael 23 / Aug / 2016 at 9:47 am

    The script is not working for me. My aim is to replace the old domain name to new domain. After i filled the necessary and i hit live button and it runs without changing anything. Any help give me necessary step to follow?

    • Michael 25 / Aug / 2016 at 12:47 am

      No one to help me here?

    • David Coveney
      David Coveney 25 / Aug / 2016 at 5:16 pm

      There are a great many reasons why it might not work – security, connection, server config and so on.

      You can get a developer to help you look into this if you need it, but they’ll usually charge. It should just work by following the on-screen instructions. You could always try an older version of the script.

    • David Coveney
      David Coveney 7 / Sep / 2016 at 12:04 pm

      It’s quite tricky – you don’t give a lot of information. For example, which version are you running, what does the dry run look like, and what are the strings you’re using?

  • Martin 30 / Jul / 2016 at 12:42 pm

    I have used this script to move three sub domains to a my current host and it is brilliant. I just go the cpanel file manager tool, browse to index.php double click and it runs. Simple. But I have just transfered a sıte as an add on domain and thıs tıme when I double clıck it just opens a txt file for downloadıng, the scrıpt doesnt run. This is the same host envıronment as my sub domaıns. The folder ıs ın the rıght place as per your notes. I have no clı experıence. Any ıdeas what I should check?

  • Miguel Araujo 12 / Jul / 2016 at 3:43 pm

    Great tool indeed !
    Only one problem: how to seek more than 20 items in preview ?
    Pagination ?

    • David Coveney
      David Coveney 12 / Jul / 2016 at 6:05 pm

      The preview is really just a quick and dirty utility to help illustrate what’s happening, I’m afraid.

  • Julian 12 / Jul / 2016 at 9:34 am

    I fear I’ve found a bug.
    If I look for something_else, it founds every occurrence of “_else”, ignoring if “something” really exists or not 🙁
    This happens with or without regex enabled.

    • Julian 12 / Jul / 2016 at 10:26 am

      I noticed this happens only in the table wp_post. This table also generates false matches, using other simple filtrers 🙁
      Can I ask for support/debugging ?
      Thank you

      • David Coveney
        David Coveney 12 / Jul / 2016 at 6:04 pm

        Hi Julian – you can indeed ask for support.

        We currently charge £150 per hour for support with this script. You can contact us at and we will be in touch to schedule some time and agree the time to be invested.

    • David Coveney
      David Coveney 12 / Jul / 2016 at 6:03 pm

      Peculiar – there’s no particular reason for not parsing an underscore but may well be a bug. We will look at this and any other issues raised when we next have time.

  • Julian 11 / Jul / 2016 at 11:36 am

    A problem with perview: if I use regex lookbehinds [e.g. /(?<!")myname/ ], it looks like it works, but "View Changes" doesn't show anything 🙁

    • David Coveney
      David Coveney 12 / Jul / 2016 at 6:01 pm

      Unfortunately this is a known weakness of the regex search. It isn’t possible to preview all regex changes. Please bear this in mind when using the script.

  • rrob 28 / Jun / 2016 at 10:34 am

    Hi, is possible to modify it to work with sqlite also?
    Thanks for reply.

  • Dies Arzola 27 / Jun / 2016 at 5:00 pm

    Hi! To my throws me this error, as I fix it?

    “The script encountered an error while running an AJAX request. “

    • Eric Zaat 6 / Sep / 2016 at 7:23 am

      Same here. First Dry Run went excellent, next runs (both dry and real) are all aborted with this error. Changed the localhost into the IP address, but this didn’t solve anything.

  • Allyson 21 / Jun / 2016 at 7:31 pm

    Great Job!

    I’m using with bigdump.php and it’s fits perfectly to a fast versioned database to a development version on server.

    Thanks for sharing this!

  • Dies Arzola 17 / Jun / 2016 at 6:21 pm

    To my throws me this error, as I fix it?

    The dry-run option was selected. No replacements will be made.
    2: Class __PHP_Incomplete_Class has no unserializer in /home/arzola10/public_html/esportes/Replace-DB-master/srdb.class.php on line 609

  • thrasos 15 / Jun / 2016 at 11:41 pm

    lifesaver! Thank you!!!

  • Lex Blagus 13 / Jun / 2016 at 2:38 am

    Man, I use this tiny little great tool everyday. Thanks a bunch for it!

  • geremy 10 / Jun / 2016 at 10:04 am

    hi after I clicked “submit DB details” it redirects to a page /searchreplacedb2.php?step=3 and nothing shows up.

  • Julian 9 / Jun / 2016 at 2:20 pm

    Possible bug ?
    Noticed in table WP_POSTMETA
    If I have fileds containing
    “searchstring, or searchstring”, or searchstring’ or searchstring@
    they are not matched (and not replaced).

    Very odd 🙁


    • Julian 9 / Jun / 2016 at 2:53 pm

      Sorry: the problem was CASE SENSITIVITY 🙁

      Is it possible to enable a flag for case insensitive ?

      • Mim McNeela
        Mim McNeela 10 / Jun / 2016 at 11:54 am

        Hi Julian

        Thanks for your feedback. We’ll add it to the list of potential features for consideration when we come to work on a new version.

        • Julian 11 / Jul / 2016 at 10:04 am

          Thank you indeed !!!
          I have another problem: If too much susbstitutions, I cannot check them all in the details popup: is it possible to have them in a file ? (I always work with the GUI). Thanks again.

      • David Coveney
        David Coveney 13 / Jun / 2016 at 10:55 am

        Hi Julian – it’s really designed as a tool for developers and developers like things to be strict. But we’ll consider this as a possibility.

        • Julian 11 / Jul / 2016 at 10:05 am

          Yes, true … don’t leave it checked as default 🙂

1 51 52 53 54 55