انتقال سایت وردپرس به دامنه جدید: هفت بار منتقل کردیم و آدرس قدیمی باقی‌مانده را شمردیم

شمارنده دستی با عدد ۰۰۹۸ روی نمایشگر، برچسب «چهار دستور SQL» بالای آن و برچسبی با نوشته old.localhost که خط قرمزی از رویش گذشته است
محصولات زیر برای شماست...
جدیدترین مقالات
دسترسی سریع
فهرست محتوا

برای انتقال سایت وردپرس به دامنه جدید، یک فروشگاه آزمایشی را هفت بار از old.localhost به new-store.localhost بردیم، هر بار با ترکیبی دیگر از ابزارها (بسته داپلیکیتور را یک بار ساختیم و دو بار نصب کردیم). بعد از هر انتقال شمردیم آدرس قدیمی چند بار در دیتابیس مانده است. فروشگاه ما وردپرس ۷٫۱٫۴ است و ووکامرس، المنتور و رنک مث دارد. داپلیکیتور پرو یک مورد باقی گذاشت، در هر دو نصب. چهار دستور SQL ساده ۹۸ مورد باقی گذاشت و دو مقدار ذخیره‌شده را ناخواندنی کرد. همان دستور روی همه ردیف‌های تنظیمات، منوی هدر را از صفحه‌ها برداشت.

اگر فقط هاست عوض شود و دامنه همان بماند، یعنی انتقال به هاست جدید، در آزمایش ما چیزی برای جایگزینی نبود. فایل‌ها و دیتابیس را کپی کردیم، چهار مقدار wp-config.php را عوض کردیم و ۲۳ صفحه از ۲۳ صفحه مثل سایت قدیمی جواب داد. بقیه این مقاله برای وقتی است که دامنه هم عوض می‌شود.

«مورد» در جدول هر بار دیده‌شدن آدرس قدیمی در دیتابیس است، همان عددی که wp db search در خط آخر با عبارت Found N matches چاپ می‌کند. «ناخواندنی» مقداری است که وردپرس نمی‌تواند از آن داده بگیرد، چون طول ثبت‌شده کنار متنش با خود متن جور نیست؛ ستون آخر جدول مقدارهایی را می‌شمارد که بعد از چند بازدید از سایت هنوز ناخواندنی‌اند.

روشمورد باقی‌ماندهصفحه‌ای که هنوز آدرس قدیمی را چاپ می‌کند (از ۲۳)مقدار ناخواندنی
فقط کپی، بدون جایگزینی۲۵۵۲۰۰
چهار دستور SQL۹۸۱۶۲
همان SQL روی همه ردیف‌های تنظیمات۷۴۱۶
wp search-replace با skip-columns=guid۱۳۹۲۰
همان با all-tables۱۰۹۲۰
با all-tables و دستور المنتور۸۵۱۰
داپلیکیتور پرو۱۰۰

از ۸۵ مورد در آخرین روش wp search-replace (با all-tables و دستور المنتور)، ۶۶ مورد ستون GUID است (شناسه‌ای که فید سایت برای هر نوشته می‌دهد) که وردپرس می‌گوید هرگز نباید عوض شود، و ۱۹ مورد در یک مقدار موقت (Transient) ووکامرس است.

اگر SSH و WP-CLI دارید، در دیتابیس سایت آزمایشی ما ترکیب wp search-replace با skip-columns=guid و all-tables و بعد دستور المنتور همه چیز را جز GUID و یک مقدار موقت عوض کرد. بدون آنها داپلیکیتور پرو یک مورد باقی گذاشت و از مرورگر کار می‌کند. بعد از انتقال در هر دو حالت باید دستور شمارش را اجرا کرد؛ اگر SSH ندارید، آن را به کسی بسپارید که دارد (راه سپردن به ما در آخر همین مقاله است).

هر روش روی همان سایت و با همان دستور شمارش آزموده شد

سایت ۳۴۷ مگابایت روی دیسک است و دیتابیس آن ۵٫۱۹ مگابایت. ووکامرس ۱۱٫۲٫۱، المنتور ۴٫۳٫۵ و رنک مث ۱٫۰٫۲۸۰ روی آن نصب است، با ۸ نوشته و ۴ برگه (بلوک‌های ویرایشگر)، یک صفحه المنتور با تصویر پس‌زمینه، ۱۲ محصول (یکی دانلودی)، ۳ سفارش و منوی هدر با ۶ آیتم. دو آدرس هم‌طول نیستند (۲۶ و ۳۲ نویسه). وردپرس بعضی تنظیم‌ها را با طول متن کنار خود متن ذخیره می‌کند، و اگر آدرس بلندتر شود و آن عدد عوض نشود، مقدار ناخواندنی می‌شود. راهنمای رسمی وردپرس هم همین را هشدار می‌دهد.

بعد از هر انتقال ۲۳ صفحه را باز کردیم: صفحه‌ها، نوشته‌ها، دو محصول، دو نقشه سایت، فید و یک مسیر ریدایرکت رنک مث. دو سایت روی یک ماشین بودند و یک پروکسی با نام میزبان تعیین می‌کرد کدام یک جواب دهد؛ جای عوض‌کردن DNS همین بود. DNS، TTL، گواهی SSL، ایمیل، زمان قطعی، سرچ کنسول و رتبه را آزمایش نکردیم. دستورهای wp این مقاله از WP-CLI ۲٫۱۲٫۰ هستند و به دسترسی SSH نیاز دارند، و آدرس‌ها و مشخصات دیتابیس در بلوک‌های این مقاله متعلق به سایت آزمایشی است؛ مقدار خودتان را بگذارید. شمارش در همه روش‌ها با یک دستور بود:

CODE
وردپرس نیاز
bash
wp db search old.localhost --all-tables --stats --matches_only --before_context=0 --after_context=0

این دستور جدول‌های دیتابیس را که ستون متنی دارند جست‌وجو می‌کند، چه افزونه‌ای ثبتشان کرده باشد چه نه.

انتقال به هاست جدید با همان دامنه: چیزی جایگزین نمی‌شود

پیش از هر انتقال یک بکاپ کامل بگیرید. بعد روی هاست قدیمی دیتابیس و فایل‌ها را بیرون می‌کشیم:

CODE
وردپرس نیاز
bash
wp db export /tmp/site.sql
tar -czf /tmp/site-files.tar.gz .

دو فایل را با SFTP یا scp به هاست جدید ببرید. دیتابیس و کاربرش باید از قبل ساخته شده باشند، چون wp db import دیتابیس نمی‌سازد. روی هاست جدید، در پوشه خالی سایت، هر دو فایل را باز می‌کنیم و چهار مقدار دیتابیس جدید را در wp-config.php می‌نویسیم:

CODE
وردپرس نیاز
bash
tar -xzf /tmp/site-files.tar.gz
wp config set DB_NAME newsite_db --type=constant
wp config set DB_USER newsite_user --type=constant
wp config set DB_PASSWORD 'change-me-123' --type=constant
wp config set DB_HOST newdb --type=constant
wp db import /tmp/site.sql

سپس نام دامنه را به هاست جدید بردیم، در آزمایش ما با همان پروکسی. هر ۲۳ صفحه همان متن و همان لینک‌های سایت قدیمی را داشت و siteurl و home همان آدرس قدیمی ماندند. راهنمای وردپرس هم می‌نویسد اگر دیتابیس و آدرس همان بماند، کپی فایل‌ها و دیتابیس کافی است. اگر نام یا کاربر دیتابیس عوض شود یا دیتابیس روی سرور دیگری باشد، wp-config.php را اصلاح کنید. کپی دیتابیس و فایل‌ها اول هر انتقال است، با دامنه جدید هم.

بعد از انتقال هر دو فایل را پاک کنید: دیتابیس اطلاعات کاربران و سفارش‌ها را دارد و بایگانی wp-config.php را.

هر دو سرور ما آپاچی با PHP یکسان بودند. انتقال بین نسخه‌های PHP یا بین آپاچی و انجین‌ایکس را آزمایش نکردیم.

جایگزینی با SQL دو مقدار را ناخواندنی کرد و منو را برداشت

اول چهار دستور REPLACE، به همان قالبی که راهنمای وردپرس برای post_content نشان می‌دهد. خود راهنما جایگزینی را فقط روی جدول wp_posts می‌داند؛ دستور چهارم ما روی wp_postmeta هم می‌رود و سومی ستون GUID را عوض می‌کند، همان ستونی که راهنما نمی‌خواهد دست بخورد:

SQL
وردپرس نیاز
UPDATE wp_options SET option_value = REPLACE(option_value, 'http://old.localhost:41200', 'http://new-store.localhost:41200') WHERE option_name IN ('siteurl','home');
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://old.localhost:41200', 'http://new-store.localhost:41200');
UPDATE wp_posts SET guid = REPLACE(guid, 'http://old.localhost:41200', 'http://new-store.localhost:41200');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'http://old.localhost:41200', 'http://new-store.localhost:41200');

بعد از آن ۹۸ مورد ماند و ۱۶ صفحه هنوز آدرس قدیمی را چاپ می‌کرد. دو مقدار ناخواندنی شد: تنظیم‌های کیت المنتور و فهرست فایل دانلودی تنها محصول دانلودی سایت. آن محصول قبل از دستور یک فایل دانلودی داشت و بعد از آن هیچ.

رنگ دلخواه کیت المنتور تا وقتی المنتور CSS را از نو نساخت روی صفحه ماند. بعد از wp elementor flush-css به رنگ پیش‌فرض المنتور برگشت. این خرابی می‌تواند دیرتر دیده شود.

دستور اول را بدون شرط نام هم اجرا کردیم، یعنی روی همه ردیف‌های جدول wp_options. ۷۴ مورد ماند و ۶ مقدار ناخواندنی شد: دو تنظیم رنک مث، یک گزارش رنک مث، یک مقدار موقت ووکامرس و همان دو مقدار قبلی. پیش از اولین بازدید، ردیف تنظیم‌های خود قالب هم ناخواندنی بود. اولین درخواست‌ها آن را با مقدار تازه‌ای جایگزین کردند که فقط یک تنظیم دارد، و منوی هدر از ۶ آیتم به صفر رسید.

دو نمونه از هدر همان صفحه: بالا با منوی ۶ آیتمی بعد از جایگزینی با Wp-Cli و دستور المنتور، پایین بدون منو بعد از Sql روی همه ردیف‌های تنظیمات

در ۱۸ صفحه‌ای که هدر داشتند، متن ۶ آیتم منو (هر کدام دو بار) نبود، و در ۱۷ صفحه عنوان تب مرورگر خط تیره‌اش را از دست داد. از ۲۳ صفحه فقط ۴ صفحه مثل سایت قدیمی بود: فید، نقشه نوشته‌ها، ریدایرکت رنک مث و صفحه تسویه حساب که سبد خالی را به سبد خرید می‌فرستد.

wp search-replace چهار جدول را جا انداخت و صفحه المنتور آدرس قدیمی را نگه داشت

دستور wp search-replace سریالایز را خودش درست می‌کند، و در اجرای ما هیچ مقداری ناخواندنی نشد. ستون GUID را کنار گذاشتیم، چون راهنمای وردپرس برای همین دستور skip-columns=guid را می‌آورد. مستندات WP-CLI می‌گوید دستور به‌طور پیش‌فرض فقط جدول‌های ثبت‌شده در wpdb را جست‌وجو می‌کند. گزینه dry-run هم کار را اجرا و گزارش می‌کند ولی چیزی ذخیره نمی‌کند؛ بار اول با آن امتحان کنید. فرمان کامل این است:

CODE
وردپرس نیاز
bash
wp search-replace 'http://old.localhost:41200' 'http://new-store.localhost:41200' --skip-columns=guid --all-tables

بدون all-tables ۱۳۹ مورد ماند و با آن ۱۰۹ مورد. تفاوت در چهار جدول افزونه‌ها بود: ۲۵ ردیف لینک‌ها و ۲ ریدایرکت رنک مث، یک پوشه دانلود تأییدشده و ۲ یادداشت مدیریت ووکامرس. ریدایرکت رنک مث بدون آن گزینه، مسیر قدیمی را به دامنه قدیمی می‌فرستاد. اگر دیتابیس با برنامه دیگری مشترک است، all-tables در جدول‌های آن هم جایگزین می‌کند؛ all-tables-with-prefix فقط در جدول‌های با همان پیشوند.

باز هم صفحه المنتور آدرس قدیمی لینک‌ها، تصویر و پس‌زمینه‌اش را داشت. المنتور داده صفحه را با یک بک‌اسلش پیش از هر اسلش ذخیره می‌کند و دستور جایگزینی با آدرس کامل سایت آن را در این داده پیدا نمی‌کند. وقتی سایت قدیمی را خاموش کردیم، پس‌زمینه و تصویر صفحه از بین رفت.

صفحه المنتور با سایت قدیمی خاموش: سمت راست پس‌زمینه خاکستری و تصویر شکسته بعد از All-Tables، سمت چپ پس‌زمینه و تصویر سالم بعد از دستور المنتور

دستور خود المنتور این را درست می‌کند، با همان دو آدرس:

CODE
وردپرس نیاز
bash
wp elementor replace-urls 'http://old.localhost:41200' 'http://new-store.localhost:41200'

چهار ردیف تغییر کرد (صفحه و سه بازبینی‌اش). المنتور فایل‌های CSS را پاک کرد و با اولین بازدید دوباره ساخته شدند. بعد از آن ۸۵ مورد ماند، همان ۶۶ GUID و یک مقدار موقت. مستندات المنتور می‌گوید بخشی از آدرس‌ها در فایل‌ها هستند و در دیتابیس نیستند.

داپلیکیتور پرو یک مورد را جا انداخت و نصب‌کننده good گزارش داد

داپلیکیتور پرو ۵٫۱٫۰ را آزمایش کردیم: یک بسته ساختیم و آن را دو بار نصب کردیم. در سایت قدیمی از منوی Duplicator Pro > Backups > Add New سه صفحه را رد کردیم: تنظیم، اسکن، ساخت. ساخت بسته ۶٫۵۵۹ ثانیه طول کشید و خروجی دو فایل بود، یک بایگانی ۱۴۹٫۴ مگابایتی و installer.php. روی هاست جدید، در پوشه خالی با دیتابیس خالی، هر دو را گذاشتیم و installer.php را در مرورگر باز کردیم.

نصب‌کننده آدرس جدید را خودش وارد کرد و آدرس قدیمی را کنارش نشان داد. ما مشخصات دیتابیس را وارد کردیم و تأییدها را زدیم. در هر دو نصب استخراج، دیتابیس و جایگزینی روی هم کمتر از ۵ ثانیه طول کشید.

صفحه نتیجه برای هر پنج خط («General Notices status»، «Files status»، «Database migration status»، «Search and replace migration status»، «Plugins») نوشت good. در دیتابیس یک مورد ماند، در هر دو نصب: پیش‌نویس برگه «سیاست حفظ حریم خصوصی» با این جمله که آدرس در آن با نقطه تمام می‌شود:

CODE
وردپرس نیاز
Our website address is: http://old.localhost:41200.

کد نصب‌کننده آدرس را فقط وقتی عوض می‌کند که بعدش اسلش، علامت سؤال، گیومه، خط جدید یا پایان مقدار بیاید. الگوهای خودش را روی نمونه‌ها اجرا کردیم. آدرس پیش از نقطه، فاصله، ویرگول یا پرانتز بسته عوض نشد. پس بعد از داپلیکیتور هم wp db search را اجرا کنید.

نصب‌کننده برخلاف اجرای wp search-replace ما ستون GUID را هم عوض کرد (۶۶ از ۶۶). در نصب‌کننده تیکی برای نگه‌داشتن GUID هست که پیش‌فرضش خاموش است؛ آن را آزمایش نکردیم. راهنمای وردپرس توضیح می‌دهد با عوض‌شدن GUID بسیاری از فیدخوان‌ها نوشته‌های قدیمی را دوباره تازه نشان می‌دهند. هر ۲۳ صفحه مثل سایت قدیمی بود و هیچ مقداری ناخواندنی نشد.

تا اولین ورود به پیشخوان، installer.php، بایگانی و پوشه نصب‌کننده روی هاست جدید می‌مانند و ۱۴ فایل از آنها آدرس قدیمی را داشتند. با ورود و تیک «Auto delete installer files» همه پاک شد و installer.php جواب ۴۰۴ داد.

دوازده مسیر را با ریدایرکت ۳۰۱ امتحان کردیم

بالای فایل htaccess سایت قدیمی این قاعده را گذاشتیم:

APACHE
وردپرس نیاز
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old\.localhost(:41200)?$ [NC]
RewriteRule ^ http://new-store.localhost:41200%{REQUEST_URI} [R=301,L]

با curl یازده مسیر قدیمی را فرستادیم، و یک مسیر دیگر که هرگز وجود نداشت، تا ببینیم صفحه ناموجود چه جواب می‌گیرد. همه در اولین پاسخ ۳۰۱ دادند و مسیر، کوئری استرینگ و نامک فارسی همان ماند. هشت مسیر با یک ریدایرکت به صفحه جدید رسیدند و سه مسیر با دو ریدایرکت: آدرس بدون اسلش پایانی، لینک کوتاه نوشته (آدرسی با شناسه p) و مسیری که ریدایرکت رنک مث هم می‌گیرد. مسیر ساختگی در سایت جدید ۴۰۴ شد. بیشترین طول زنجیره ۲ بود.

صفحه گوگل درباره جابه‌جایی سایت (به‌روز ۲۹ مرداد ۱۴۰۵) ریدایرکت دائمی سمت سرور، یعنی ۳۰۱ یا ۳۰۸، را توصیه می‌کند و می‌گوید از زنجیره‌ای‌کردن ریدایرکت‌ها دوری کنید؛ اگر ناگزیرید، زنجیره را کوتاه نگه دارید، ترجیحاً ۳ ریدایرکت یا کمتر. ریدایرکت‌ها را تا جای ممکن و معمولاً دست‌کم ۱ سال نگه دارید. برای تغییر دامنه، در سرچ کنسول «Change of Address» را برای سایت قدیمی ثبت کنید؛ برای انتقال از HTTP به HTTPS لازم نیست. نقشه جدید سایت را هم همان‌جا ثبت کنید. این بخش‌ها را آزمایش نکردیم.

بعد از هر انتقال این سه چیز را ببینید

  1. دستور شمارش را اجرا کنید. برای دیدن جدول و ستون هر مورد همان دستور را بدون matches_only بزنید. راهنمای وردپرس تأکید می‌کند GUID عوض نشود. مقدار موقت را وردپرس دوباره می‌سازد و همان راهنما حذفش را بی‌خطر می‌داند. هر مورد دیگر را باید دستی ببینید.
  2. منوی هدر، یک محصول دانلودی و صفحه‌ای را که با صفحه‌ساز ساخته‌اید باز کنید، با سایت قدیمی خاموش. تصویر خراب را ما همین‌طور دیدیم.
  3. قاعده ریدایرکت را با curl روی چند آدرس بزنید، از جمله یکی با کوئری استرینگ.

اگر می‌خواهید انتقال را به ما بسپارید، درخواست را در فرم پشتیبانی ثبت کنید. صفحه خدمات قیمتی برای انتقال سایت ندارد. اگر بعد از انتقال صفحه‌ای خطای ۵۰۰ داد، علت‌های خطای ۵۰۰ را ببینید.

افزونه‌های انتقال دیگری مثل All-in-One WP Migration و WP Migrate را هم آزمایش نکردیم.

پرسش‌های متداول

اگر فقط هاست عوض می‌شود، باید آدرس‌ها را جایگزین کنم؟

در آزمایش ما نه. فایل‌ها و دیتابیس را کپی کردیم، چهار مقدار wp-config.php را عوض کردیم و ۲۳ صفحه از ۲۳ صفحه مثل سایت قدیمی جواب داد. این انتقال بین دو سرور آپاچی با PHP یکسان بود.

جایگزینی آدرس با دستور SQL امن است؟

در آزمایش ما چهار دستور REPLACE دو مقدار را ناخواندنی کرد، تنظیم‌های کیت المنتور و فایل دانلودی یک محصول را، و همان دستور روی همه ردیف‌های تنظیمات منوی هدر را از ۶ آیتم به صفر رساند. دستور wp search-replace سریالایز را خودش درست می‌کند.

چرا بعد از wp search-replace هنوز آدرس قدیمی در دیتابیس هست؟

بدون all-tables دستور فقط جدول‌های ثبت‌شده در wpdb را جست‌وجو می‌کند و در آزمایش ما چهار جدول رنک مث و ووکامرس را نخواند. المنتور هم آدرس را با بک‌اسلش ذخیره می‌کند. با all-tables و بعد wp elementor replace-urls فقط GUID و یک مقدار موقت ماند.

بعد از انتقال با داپلیکیتور پرو باید دیتابیس را دوباره جست‌وجو کنم؟

بله. در آزمایش ما نصب‌کننده good گزارش داد و یک مورد مانده بود: آدرسی که در متن یک برگه با نقطه تمام می‌شد. کد نصب‌کننده آدرس را فقط پیش از اسلش، علامت سؤال، گیومه، خط جدید یا پایان مقدار عوض می‌کند.

ریدایرکت ۳۰۱ را چقدر باید نگه دارم؟

صفحه گوگل درباره جابه‌جایی سایت می‌گوید تا جای ممکن و معمولاً دست‌کم ۱ سال. برای تغییر دامنه، Change of Address را در سرچ کنسول ثبت کنید؛ برای HTTP به HTTPS لازم نیست. ما این بخش را آزمایش نکردیم.

تصویر سمانه جعفری
سمانه جعفری
پیشنهاد میکنیم این مقالات را هم بخوانید

دیدگاه یا پرسش خود را بنویسید