DISCLAIMER: Proceed AT YOUR OWN RISK!!!
The following details are meant to help people who are in desperate need of creating a staging WordPress website or migrating to a new location and the WordPress Import and Export feature isn't working for them. I've done this many times myself and make use of special scripting tools and custom built utilities to aid in this process. There aren't a lot of online resources that walk you through this process and for those guides that do exist, most are just wrong or leave out critical steps.
For those who review these steps and cannot complete them as presented, these notes may be useful for a developer to reference. Best of luck!!!
Always Backup MySQL Database and Website Files if you proceed. Again, Proceed At Your Own Risk!!!
Advanced Steps to Create a Mirror Copy of an Existing WordPress Website
Objective Notes:
The steps in this guide apply to what I did for the website on this thread. The actual domain name has been replaced with domain.com. The objective of this technical walk through is to create a staging copy of the LIVE WordPress website to apply a complete redesign which is schedule to be released at a future date. Once completed, the LIVE website will be taken down and replaced with the updated Staging Website. The challenge is WordPress Export / Import utility doesn't work well as presented in this thread. Hopefully this guide will provide people great assistance in this process as a LAST RESORT.
Prepare New Subdomain: web.domain.com
Step 1: Go To CPanel (or the website management tool your host provides) and create a new subdomain called "web". Set the Document Root to /public_html/web/, where /public_html/ is the name of your root web folder with public access. Some servers name this /htdocs/ and so on.
Copy Files from Live Site to New Sub Domain Folder: /web/
Step 1: From CPanel (or other admin app) open your File Manager app and highlight all essential folders and files in the /public_html/ folder used by your LIVE website.
Example of File and Folder Names:
- /public_html/wp-admin/
- /public_html/wp-includes/
- /public_html/wp-content/
- /public_html/wp-config.php
...and so on and so forth.
Step 2: From the web based File Manager app, click the "Copy" button and specify destination to be:
- /public_html/web/
This will move all essential files to the new Document Root created in Step 1.
Setup new MySQL Database:
Step 1: From CPanel (or other admin app), open MySQL Database Manager to create a new database and take note of the name. Assign the same MySQL username used by LIVE WordPress Database. In this setup, I also assigned the MySQL User all privileges to the new database.
Step 2: From CPanel, open phpMyAdmin, select the LIVE WordPress Database, select Export, and run the Export to File.
Modify SQL Export File:
Step 1: Apply Search and Replace on SQL Export File to add "web" to "domain.com" and "public_html"
This step is quite involved and requires a great deal of Regular Expressions guarantee you do not apply the "web" to domain.com where domain.com is used as an email address or in a sentence.
The gist of this step is to complete the following Find and Replace steps in the following order with the rules listed:
- Replace: public_html with public_html/web ( 21 Replacements )
Replace: public_html/ with public_html/web/ ( 11 Replacements )
Replace domain.com with web.domain.com ( 3,055 Replacements )
- Where domain.com is not any of the following:
- "www.domain.com" (prefixed with "www.")
- " domain.com" (preceded by a space indicating it is used in a sentence)
- "@domain.com" (preceded by an @ sign indicating it is used in an email address)
Replace www.domain.com with web.domain.com: ( 4,153 Replacements )
- Where www.domain.com is not preceded with a space indicating it is in a sentence.
The result is 7,245 replacements of 7,378 possible matches. What makes this tedious without regular expressions is not applying "web" to (domain.com or public_html) to the 133 instances where domain.com is used an email address or in a sentence, not a link.
Step 2: Fix Serialized String References in SQL Export File.
What a nightmare... This is the part where life starts to get painful. WordPress makes use of what is called serialized strings. This single concept is what makes migrating WordPress or any PHP platform that utilizes serialized strings so painful.
For instance, many plugins and WordPress itself saves many settings in a single database field using a pattern similar to the following simple example:
Setting Owner: Dashboard Widget Options:
- Setting: 'home' => 'http://domain.com'
- Serialized in Database and in SQL Export file as:
a:4:{s:24:"dashboard_incoming_links";a:5:{s:4:"home";s:17:"http://domain.com"; ... and so on for a total 917 characters.
Specifically, when making the change to:
s:17:"http://domain.com";
By adding "web.":
s:17:"http://web.domain.com";
Will make all settings in this database record impossible to read / load in PHP. The reason is the s:17 means PHP expects 17 characters between the quotes that follow. By adding 4 new characters with "web.", the new string value has 21 characters and needs to be updated accordingly:
s:21:"http://web.domain.com";
In the case of this website, there were 201 instances in serialized strings that had to be updated. In some cases, http://web.domain.com might be in a longer string, multiple times, looking something like:
s:2432:"Insert a bunch of text <a href="domain.com/somepage/">Some Link</a> continue with a bunch of text and other links.";
If s:2432 is not updated to reflect the exact number of characters between the quotes that follow, the entire string cannot be loaded.
Now imagine having to review this for 201 instances in a SQL Export File with 11,260 lines. Although I presented what needs to be done, this is a daunting task for anyone to overcome and do it accurately.
I have faced this issue before and have written utility scripts that gets this done in seconds. However, the script isn't something that is user friendly and requires tweaking on a site by site basis. So it only took me a few minutes to complete.
Importing SQL File into New Database:
Now that the SQL File is fully prepped for the new sub domain all paths and images are pointing to the proper new locations, you can import the modified SQL scripts into the new database.
Step 1: From CPanel, open phpMyAdmin, select the NEW WordPress Database, select Import, select the modified file on your computer, click "Go".
Step 2: Update wp-config.php file via FTP Client or CPanel File Manager code editor so the following database names are updated properly:
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'your-db-name');
/** MySQL database username */
define('DB_USER', 'your-db-username');
/** MySQL database password */
define('DB_PASSWORD', 'your-password');
Only other file to consider updating is the .htaccess file. However, based on what I saw, nothing needed to be modified for the staging setup of this new website.
Converting Staging Site to LIVE Site:
After applying the redesign via WordPress interface, the final step is to modify the web.domain.com to become www.domain.com.
Without going into every possible detail, follow the summary steps below:
Step 1: Repeat the steps above that involve exporting the new database to a file.
Step 2: Open the New SQL Export file, search for "web.domain.com" and replace with "www.domain.com".
Since the number of characters are the same, no need to revisit the serialized string issue.
Step 3: Import Modified SQL File into a New Database. See note above on how to do this.
Step 4: Copy all new images from /public_html/web/wp-content/uploads/ folder into /public_html/wp-content/uploads/.
Step 5: Copy any new plugins from:
- From: /public_html/web/wp-content/plugins/plugin_name/
- To: /public_html/wp-content/plugins/plugin_name/
Step 6: Copy any new themes from:
- From: /public_html/web/wp-content/themes/theme_name/
- To: /public_html/wp-content/themes/theme_name/
Step 7: Update wp-config.php file with new database values.