İçeriğe geç
Yapılandırma

WordPress Veritabanında URL Değiştirme: Serileştirilmiş Veriyi Bozmadan Nasıl Yapılır

Bir WordPress site adresini veritabanında değiştirirken widget'ları, menüleri ve tema ayarlarını boşaltmayın. Serileştirilmiş veriyi koruyan WP-CLI komutunu kullanın.

Yayınlandı

Bir WordPress veritabanında düz bir UPDATE ... SET column = REPLACE(column, 'oldurl', 'newurl') çalıştırmayın. Metni doğru şekilde değiştirir ve aynı anda ayarlarınızı yok eder; çünkü WordPress dizileri ve nesneleri PHP ile serileştirilmiş metin olarak saklar ve bu biçim içerdiği her metnin bayt uzunluğunu da kaydeder. Ham bir SQL değiştirme işlemi metni yeniden yazar ama kayıtlı uzunluğa hiç dokunmaz; değer de okunamaz hale gelir.

Bunun yerine serileştirmeyi tanıyan bir araç kullanın. Komut satırında bu araç wp search-replace. Önce veritabanını yedekleyin, kuru çalıştırmayla deneyin, sonra gerçekten çalıştırın.

Asıl bozulan ne

PHP ile serileştirilmiş bir metin şöyle görünür:

s:18:"http://example.com"

Buradaki 18, ardından gelen metnin bayt uzunluğu. Sayın — http://example.com tam olarak 18 karakter.

Şimdi saklanmış bir tema ayarı düşünün:

a:1:{s:4:"logo";s:18:"http://example.com";}

http:// yerine https:// koyan düz bir SQL değiştirme çalıştırın, elinizde şu olsun istersiniz:

a:1:{s:4:"logo";s:19:"https://example.com";}

Ama olmaz. Elinizde şu olur:

a:1:{s:4:"logo";s:18:"https://example.com";}

Metin artık 19 bayt ama hâlâ 18 olduğunu iddia ediyor. PHP bildirilen uzunluğu okur, 18 bayt ilerler, beklediği yerde kapanış tırnağını ve noktalı virgülü bulamaz ve pes eder. Dizinin tamamı çözümlenemez.

Neden sessizce başarısız olur

Bu hatayı bu kadar pahalı yapan kısım tam olarak burası. WordPress bir hata fırlatıp durmaz. Bir seçeneği okuduğunda değeri kendi çözümleme yardımcısından geçirir, PHP bozuk veri için false döndürür ve WordPress kodunuza sanki o seçenek hiç kaydedilmemiş gibi davranan bir değer verir. Eklenti ya da tema da kendi varsayılanına döner.

Yani belirti bir hata sayfası değil. Belirti şu:

  • Widget’lar kenar çubuklarından kaybolur
  • Özelleştirici ayarları tema varsayılanlarına döner
  • Bir sayfa oluşturucunun düzen verisi boş gelir ve sayfa bomboş açılır
  • Eklenti ayar sayfaları yeni kurulmuş gibi görünür
  • Menüler atandıkları konumları kaybeder

Yönetim panelinde hiçbir şey bir sorun olduğunu söylemez. Satır hâlâ veritabanındadır, hâlâ doğru görünen metinle doludur. Yalnızca uzunluk öneki bir iki bayt kaymıştır. PHP çözümleme başarısız olduğunda bir uyarı üretir, ama hata gösterimi kapalı bir canlı sitede bunu kimse görmez. WP_DEBUG sabitini WP_DEBUG_LOG etkinken ve WP_DEBUG_DISPLAY kapalıyken açmak, bu uyarıları okuyabileceğiniz bir kayıt dosyasına yazar.

Hasar da her yere eşit dağılmaz. Basit tekil değerler — siteurl, home, düz yazı içeriği, kendi sütununda duran bir adres — saf bir değiştirmeden sorunsuz çıkar. Yalnızca serileştirilmiş değerler bozulur. Hatalı bir değiştirmenin ilk bakışta çoğu zaman işe yaramış gibi görünmesinin nedeni budur.

Hiçbir şeye dokunmadan önce wp-config.php dosyasına bakın

wp-config.php dosyası WP_HOME veya WP_SITEURL tanımlıyorsa, bu sabitler veritabanındaki her şeyi ezer. wp_options tablosunu değiştirmek hiçbir işe yaramamış gibi görünür. Sorunun veritabanında olduğuna karar vermeden önce şuna benzer satırları arayın:

define( 'WP_HOME', 'http://example.com' );
define( 'WP_SITEURL', 'http://example.com' );

Ya bunları yeni adrese göre güncelleyin ya da tamamen kaldırıp yönetimi veritabanına bırakın.

Önce yedek alın, hem de gerçekten

Serileştirme bozulması her zaman kolayca geri alınabilen bir şey değildir. Uzunluk öneki ile içerik bir kez birbirine uymadığında, orijinal değer bozuk değerden geri getirilemez — asıl metni bilmeden doğru uzunluğun ne olması gerektiğini bilemezsiniz. Tek gerçek geri alma yolu yedektir.

wp db export backup-before-replace.sql

WP-CLI yoksa mysqldump ile:

mysqldump -u USER -p DBNAME > backup-before-replace.sql

Mümkünse yedeği sunucunun dışında tutun. Site kök dizininde duran bir yedek hem geri dönüş noktası hem de güvenlik açığıdır.

Güvenli komut

WP-CLI’nin search-replace komutu her değeri çözer, çözülmüş yapının içinde gezinir, değişikliği orada yapar ve doğru uzunluklarla yeniden serileştirir. Önce kuru çalıştırma:

wp search-replace 'http://example.com' 'https://example.com' --dry-run --all-tables --skip-columns=guid

Raporu okuyun. Her tablo ve sütun için kaç değişiklik yapılacağını söyler. Tablo listesi yanlış görünüyorsa ya da tanımadığınız bir tabloda binlerce eşleşme varsa, durun ve gerçekten çalıştırmadan önce bakın.

Sonra çalıştırın:

wp search-replace 'http://example.com' 'https://example.com' --all-tables --skip-columns=guid --report-changed-only

Parametreler hakkında dürüst notlar:

  • --all-tables, WordPress’in kendi kaydetmediği tabloları da kapsar; eklenti verileri çoğu zaman oralarda durur. Bu olmadan bazı eklenti tabloları tamamen atlanır.
  • --skip-columns=guid önemli. guid, besleme okuyucuları için kalıcı bir kimliktir, canlı bir adres değil. Onu yeniden yazmak, abonelerin tüm arşivinizi yeni yazı sanmasına yol açabilir.
  • Arama yaparken sondaki eğik çizgiyi ve dokunmak istemediğiniz protokol varyantlarını dışarıda bırakın. Çıplak example.com aramak e-posta adreslerini ve yazı metinlerindeki her geçişi de vurur.

Komut satırını kullanamıyorsanız, serileştirmeyi tanıyan taşıma eklentileri aynı çözümleme işini yönetim ekranından yapar. Aradığınız davranış, açıkça “serileştirilmiş veriyi işler” şeklinde belirtilmiş olmalı; bir araç bunu söylemiyorsa yapmadığını varsayın.

Hangi tablolar ve sütunlar işin içinde

TabloSütunSerileştirme riski
wp_optionsoption_valueYüksek — widget’lar, tema ayarları, geçici veriler, çoğu eklenti ayarı
wp_postmetameta_valueYüksek — sayfa oluşturucu düzenleri, özel alan dizileri
wp_usermetameta_valueYüksek — yetkiler, ekran ve panel tercihleri
wp_termmetameta_valueOrta — eklentilere bağlı
wp_postspost_content, guidİçerik için düşük, ama kısa kod nitelikleri ve blok işaretlemesi adres taşır
wp_commentscomment_content, comment_author_urlDüşük
wp_linkslink_url, link_imageDüşük ve çoğu zaman kullanılmıyor

Çoklu sitede bunlara wp_blogs, wp_site, wp_sitemeta ve site başına gelen wp_2_options, wp_3_options gibi tabloları ekleyin. Çoklu sitede adres değiştirmenin arama ve değiştirmenin ötesinde ek kuralları vardır — onu ayrı bir iş olarak ele alın.

search-replace’in tam olarak çözmediği durumlar

Sınırlar konusunda dürüst olalım:

Veritabanında saklanan JSON. Bazı sayfa oluşturucular düzen verisini eğik çizgileri kaçışlı JSON olarak saklar, yani adresiniz https://example.com yerine https:\/\/example.com biçiminde görünür. Normal biçimi aramak bunu ıskalar. Kaçışlı metin için ikinci bir tur gerekebilir. Bir kopya üzerinde deneyin.

Base64 ile kodlanmış değerler. Bir eklenti ayarları saklamadan önce kodluyorsa, metin tabanlı hiçbir değiştirme adresi göremez. Bu ayarların genellikle eklentinin kendi ekranından yeniden girilmesi gerekir.

Dosyalara sabit yazılmış adresler. functions.php içine, bir alt tema şablonuna ya da sabit bir dosya yoluna yazılmış her şey veritabanında değildir ve dokunulmaz. Tema klasörünü ayrıca tarayın.

Önbelleğe alınmış ve üretilmiş çıktı. Nesne önbelleği, sayfa önbelleği ve CDN kopyaları doğru bir değiştirmeden sonra bile eski adresleri sunmaya devam eder. Önce hepsini temizleyin, sonra değiştirme başarısız oldu sonucuna varmadan tekrar bakın.

Hatalı sorguyu zaten çalıştırdıysanız

Yedeği geri yükleyin. Cevap bu; çoğunlukla işe yaramayan bir onarım yordamı önermek yerine bunu açıkça söylemek daha doğru.

Yedek yoksa kurtarılabilir alan dardır: hiç serileştirilmemiş değerler sağlamdır, bozulmuş serileştirilmiş olanların ise elle yeniden oluşturulması ya da ilgili ayar ekranı yeniden kaydedilerek sıfırlanması gerekir. Bir widget alanını yeniden kaydetmek, bir menü konumunu yeniden seçmek ya da bir eklentinin ayarlarını yeniden girmek, bozuk değerin üzerine doğru serileştirilmiş taze bir değer yazar. Yorucu ama işe yarar ve bozuk satırları oldukları yerde bırakıp siteye bakacak bir sonraki kişinin kafasını karıştırmaktan iyidir.

Herhangi bir şey çalıştırmadan önce doğru ifadeleri üretmek için onları WordPress arama ve değiştirme SQL aracıyla oluşturun — hangi sütunlara düz SQL ile dokunmanın güvenli olduğunu, hangilerinin serileştirmeyi tanıyan bir işlem gerektirdiğini gösterir; böylece bir komuta bağlanmadan önce ayrımı görebilirsiniz.

FAQ

Sorular

Düz bir SQL REPLACE komutu WordPress sitesini neden bozar?

Çünkü WordPress dizileri ve nesneleri PHP ile serileştirilmiş metin olarak saklar ve bu biçim içindeki her metnin bayt uzunluğunu da kaydeder. Ham bir REPLACE metni değiştirir ama eski uzunluk sayısını olduğu gibi bırakır. PHP de değeri çözmeyi reddeder, WordPress varsayılana döner ve ayarlar yanlış değil, bomboş görünür.

Bir WordPress site adresini veritabanında değiştirmenin en güvenli yolu nedir?

Önce veritabanının tam yedeğini alın, sonra WP-CLI komutu wp search-replace'i önce kuru çalıştırmayla deneyin. WP-CLI her değeri çözer, çözülmüş yapının içinde değişikliği yapar ve uzunlukları düzelterek yeniden serileştirir. Komut satırına erişiminiz yoksa serileştirmeyi tanıyan taşıma eklentileri aynı işi yönetim ekranından yapar.

Eski URL hangi tablolarda duruyor?

Başlıca wp_options, wp_posts, wp_postmeta, wp_usermeta, wp_termmeta ve wp_comments. Serileştirme tehlikesi wp_options tablosunda ve meta_value sütunlarında yaşar; çünkü widget'lar, tema ayarları, geçici veriler ve sayfa oluşturucu verileri dizi olarak saklanır. Çoklu sitede wp_blogs, wp_site ve wp_sitemeta tabloları da alan adını taşır.

wp-config.php dosyası adresi tanımlıyorsa veritabanını değiştirmek işe yarar mı?

Hayır. wp-config.php dosyası WP_HOME veya WP_SITEURL tanımlıyorsa, bu sabitler wp_options içindeki siteurl ve home değerlerini ezer. Sabitler güncellenene veya kaldırılana kadar veritabanını değiştirmek gözle görülür hiçbir sonuç vermez. Önce wp-config.php dosyasına bakın; başarısız taşımaların çoğunun açıklaması o tek satırdır.

guid sütununu da değiştirmeli miyim?

Hayır. guid, besleme okuyucuları için kalıcı bir kimliktir, çalışan bir adres değil; onu yeniden yazmak beslemeye abone olanların tüm eski yazılarınızı yeniden yeni gibi görmesine yol açabilir. WP-CLI çalıştırırken guid için skip-columns kullanın. Tek yaygın istisna, hiç herkese açık beslemesi veya abonesi olmamış bir sitedir.

Hatalı bir değiştirme sonrası bir değerin bozulduğunu nasıl anlarım?

Bozuk serileştirilmiş değerler veritabanında normal görünür ama WordPress tarafında boş döner. Widget'lar kaybolur, tema özelleştirici ayarları sıfırlanır ve eklenti seçenekleri hiçbir hata mesajı vermeden varsayılana döner. WP_DEBUG ve WP_DEBUG_LOG açıldığında çözümleme uyarısı görünür hale gelir. Bildirilen metin uzunluğunu gerçek bayt sayısıyla karşılaştırmak da bunu doğrudan doğrular.