Dlaczego moja baza danych importuje dane widgetu tekstowego?

46

Na naszym komputerze programistycznym utworzyłem witrynę w WordPress. W używanym przez nas temacie istnieje wiele stref widżetów do wyświetlania tekstu (pasek boczny i strona główna). Użyłem prostych widgetów tekstowych we wszystkich tych strefach, aby umieścić nasze wyświetlane informacje.

Kiedy przeprowadziłem migrację strony do wersji produkcyjnej, skorzystałem z wtyczki WP-DB-Backup, aby zrobić migawkę bazy danych. Następnie poddałem edycji wynikowy plik .sql, aby zaktualizować wszystkie ścieżki do plików i odwołania do adresów URL, aby wskazywały na naszą stronę produkcyjną.

Po utworzeniu bazy danych, strony internetowej i skopiowaniu wszystkich plików do witryny produkcyjnej uruchamiam plik .sql z wiersza polecenia mysql, aby zaimportować dane do nowej bazy danych.

Jednak kiedy idę na stronę produkcyjną, część tekstu pojawia się, a część nie. Kiedy patrzę na sekcję widżetów w witrynie, w niektórych strefach widżetów brakuje widżetów tekstowych. Widżety tekstowe nie są nawet widoczne w strefie „Nieaktywny widget”, po prostu ich nie ma.

Próbowałem nawet powtórzyć ten proces przy użyciu wtyczki BackWPup, zauważając, że składnia SQL jest inna, gdy zrzuca bazę danych.

Dlaczego tracę dane widżetu tekstowego podczas importu?

Dillie-O
źródło
Po drodze trochę kopałem, a jedyne, co mogę wymyślić, to to, że informacje o widżecie są przechowywane w tabeli wp_options, która dziwnie koduje niektóre z jej danych. Nie byłem jeszcze w stanie wypróbować tego z innym motywem, aby sprawdzić, czy jest on związany z tematem.
Dillie-O,

Odpowiedzi:

44

Oto twój problem:

Następnie poddałem edycji wynikowy plik .sql, aby zaktualizować wszystkie ścieżki do plików i odwołania do adresów URL, aby wskazywały na naszą stronę produkcyjną.

Nie możesz tego zrobić. WordPress przechowuje wiele opcji jako „serializowane dane”, które zawierają zarówno ciąg znaków rzeczy, jak i ich długość . Kiedy więc zmodyfikujesz adres URL i zmieni się długość, dane serializowane nie będą już poprawne, a PHP je odrzuci.

Problemem długoterminowym jest to, że zasadniczo robisz to źle. Jeśli konfigurujesz witrynę programistyczną, która będzie podlegać migracji danych, powinna ona mieć dokładnie ten sam adres URL, co witryna produkcyjna. Możesz ręcznie edytować plik HOSTS, aby nadać tej domenie produkcyjnej (np. Example.com) inny adres IP (np. 127.0.0.1), a zatem „produkcyjny” adres URL stanie się witryną programistyczną, tylko dla Ciebie. Następnie możesz utworzyć swoje dane i linki oraz wszystko inne przy użyciu tego produkcyjnego adresu URL, a podczas migracji danych nic o tym nie trzeba zmieniać.

Jednak w krótkim okresie nie używaj prostego wyszukiwania / zamiany tekstu w pliku SQL. Jak odkryłeś, to psuje rzeczy.

I waham się, czy to zasugerować, ale istnieje sposób na zmianę kodu podstawowego WordPress w celu obsługi tych zepsutych serializacji. Musisz zmodyfikować plik wp-include / functions.php i zmienić funkcję może_unserialize () na:

function maybe_unserialize( $original ) {
    if ( is_serialized( $original ) ) {
        $fixed = preg_replace_callback(
            '!(?<=^|;)s:(\d+)(?=:"(.*?)";(?:}|a:|s:|b:|i:|o:|N;))!s',
            'serialize_fix_callback',
            $original );
        return @unserialize( $fixed );
    }
    return $original;
}
function serialize_fix_callback($match) { return 's:' . strlen($match[2]); }  

To NIE jest realne długoterminowe rozwiązanie. Powinien być używany tylko do podniesienia Cię do działania i natychmiastowego działania. Na dłuższą metę musisz naprawić proces programowania, aby nie trzeba było na początku tego typu mungowania adresów URL.

Otto
źródło
@Otto doskonała odpowiedź. Szybkie pytanie, czy zmodyfikowanie nieserializowanej tabeli obiektów blob / tekstowych, takich jak wp_posts poza MySql, wpłynęłoby na jakiekolwiek serializowane dane w wp_post_meta lub wp_options? Miałem ten sam problem z widżetem tekstowym, ale nie dotknąłem wp_options, modyfikowałem tylko wp_posts.
Chris_O,
Wow, nigdy nie zdawałem sobie sprawy z tego, co dzieje się z danymi, ale ma to pełny sens! Wielkie dzięki!
Dillie-O
4
Innym sposobem obejścia tego problemu przez niektóre osoby jest nadanie systemowi programistycznemu nazwy domeny „przyklad.dev” zamiast „przyklad.com”. W ten sposób długości nie zmieniają się dla ciągów, gdy przenoszą je do produkcji. Wolę metodę pliku HOSTS.
Otto
3
2016 i wordrepss nadal zapisuje dane zserializowane w bazie danych. most famous worst codenagroda nie musi już szukać.
Ejaz
1
DZIĘKUJĘ CI!!! Dobra uwaga i świetny hack. Ogólnie dostaję ten hack, aby zwrócić wszystkie dane, a następnie po prostu zaktualizuj istniejące ustawienia ponownie, a po usunięciu tego kodu działa idealnie.
Ivijan Stefan Stipić
10

Aby rozwiązać ten problem, zawsze używam narzędzia WordPress Serialized Search & Replace podanego tutaj. Działa idealnie bez żadnych problemów. Używam tego od dawna we wszystkich moich wymaganiach dotyczących migracji witryny. To naprawdę rozwiązuje problemy z migracją programistycznej bazy danych do produkcji.

https://interconnectit.com/products/search-and-replace-for-wordpress-databases/

Subharanjan
źródło
1
Tak, korzystam z tego skryptu od lat i bardzo go polecam
davemac
Pracował dla mnie przez większość czasu. Ale w tym tygodniu, kiedy zastąpiona http://localhost/Me/site_nameprzez http://site.dev(od jednego do drugiego hosta lokalnego) za pomocą v 3.0.0 I nie stracić swoje pozycje menu widgetów i dość dziwnie. Być może więc ten problem dotyczy również długości łańcucha.
rhand
Używam .. ale nigdy nie spotkałem się z tą sytuacją. Czy możesz pobrać starszą wersję tego skryptu i spróbować ponownie? Spróbuj wymienić localhost/Me/site_namez site.dev.
Subharanjan
Url się zmienił (teraz https zamiast http): interconnectit.com/products/…
Koryonik
Wspaniały scenariusz. Zduplikowałem bazę danych MySQL z PHPMyAdmin ze starej do nowej - bez żadnych zmian adresów URL - a potem poszedłem do folderu nowej witryny, w której były świeże pliki WP (wraz z odpowiednim wp-config.php, z plikiem nowe referencje DB), dodał skrypt i zajął się wszystkim. Dane serializowane są aktualizowane wzdłuż normalnych adresów URL. Łatwo i szybko! Wysoce rekomendowane. Ważne: nie zapomnij usunąć skryptu po jego użyciu, ponieważ ma on dostęp do twoich danych DB!
Orzeszki ziemne
7

Odpowiedź Otto jest natychmiastowa. Odkryłem to również na własnej skórze.

Udało mi się jednak obejść ten problem za pomocą fajnego skryptu ze strony http://spectacu.la/search-and-replace-for-wordpress-databases/

Aby przeprowadzić migrację WordPressa i nową nazwę adresu URL / domeny, wykonaj następujące czynności:

  1. Zrób zrzut DB (np. Używając phpmyadmin) istniejącego wordpress
  2. Przywróć zrzut w obecnym stanie (bez potrzeby modyfikacji) do nowej lokalizacji
  3. Rozpakuj skrypt z spectacu.la do folderu domowego wordpress (nie jest to wtyczka ...)
  4. Uruchom skrypt na nowej stronie, wskazując na nią przeglądarkę, np. Http: //new-website.url/searchreplacedb.php
  5. Nie zapomnij usunąć skryptu z nowego domu Wordpress
Yoav Aner
źródło
1
Wiem, że to trochę stare, ale gdzie mam określić nową nazwę bazy danych, jeśli przywracam zrzut w obecnej postaci? nie powinienem przynajmniej umieszczać nowej nazwy bazy danych w drugim kroku? Dziękuję za te informacje
andresmijares
Nie jestem pewien, czy w pełni rozumiem twoje pytanie. Przywracanie bazy danych można wykonać za pomocą narzędzi takich jak phpmyadmin i możesz nadać jej nową nazwę lub użyć starej nazwy. Skrypt, o którym wspomniałem, po prostu zmienia tekst w bazie danych po jej przywróceniu.
Yoav Aner
Cześć Yoav, dzięki za odpowiedź. Mam na myśli, że kiedy eksportuję bazę danych, zwykle zmieniam nazwę bazy danych na nową i zmieniam linki do domeny. Powiedziałem to, że w kroku drugim mówisz, że przywróć zrzut bez modyfikacji, chciałem tylko wiedzieć, czy to dosłownie, czy muszę przynajmniej zmienić nazwę bazy danych. Wiem, że to może być fałszywe pytanie, jestem po prostu trochę zagubiony, jeszcze raz dziękuję za twoją odpowiedź
andresmijares
Nie wiem, jak zrzucić bazę danych, ale jeśli użyjesz narzędzia „eksportuj” phpmyadmin, to nie ma znaczenia, jaką to nazwę bazy danych. Możesz użyć eksportu i zaimportować go z powrotem do dowolnej innej bazy danych. Ogólnie rzecz biorąc, jeśli chodzi o punkt 2, myślę, że zmiana nazwy bazy danych jest w porządku.
Yoav Aner
2

OP był nadgorliwy podczas wyszukiwania i zamieniania pliku eksportu bazy danych i ostatecznie zmienił występowanie „wp_” w niektórych serializowanych danych. Rozwiązaniem jest być bardziej oszczędnym w wyszukiwaniu i zamianie, włączając backtrick w wyrażenie regularne, a następnie ręcznie aktualizując pozostałe klucze w bazie danych po zaimportowaniu.

Jeśli przeprowadzasz migrację i zmieniasz prefiks i podoba Ci się podejście bardziej ręczne, wykonaj następujące czynności (dotyczy to tylko problemów PO i nie dotyczy aktualizacji adresu URL witryny)

  1. Wykonaj kopię zapasową i przenieś plik SQL eksportu bazy danych do nowego środowiska (mój przykład zakłada nazwę pliku backup_YYYY-MM-DD.sql)
  2. Wykonaj masowe wyszukiwanie i zamień w pliku SQL, aby zmienić nazwy tabel w celu użycia nowego prefiksu (PRZED zaimportowaniem pliku SQL!). Jednym ze sposobów, aby to zrobić, byłoby użycie jedno-liniowego Perla, takiego jak: perl -p -i.bak -e "s /` wp_ / `myprefix_ / g" backup_YYYY-MM-DD.sql
  3. Zaimportuj dane SQL do bazy danych
  4. Zaktualizuj dowolne klucze w ramach opcji _ zawierających prefiks zakodowany na stałe: aktualizacja myprefix_options set nazwa_opcji = concat („myprefix _”, substr (nazwa_opcji, 4)) gdzie nazwa_opcji jak „wp_%”
  5. Zaktualizuj dowolne klucze w obrębie _user_meta, które zawierają zakodowany na stałe prefiks: update myprefix_usermeta set meta_key = concat ('myprefix _', substr (meta_key, 4)) gdzie meta_key jak 'wp_%'
Tom Auger
źródło
0

Użyłem wtyczki WP Migrate , która zastępuje łatki http i foldery. Mam jeden problem podczas importowania, ale rozwiązałem umieszczanie następujących wierszy u góry wygenerowanego kodu SQL:

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

Próbowałem również z narzędziem Search And Replace (v2.1), na które odpowiedział @Yoav, ale nadal psuje moje zserializowane dane.

Ricardo Martins
źródło
Cześć Ricardo, Witamy w WordPress Answers! Obszar, który opublikowałeś jest zarezerwowany na odpowiedzi na pierwotne pytanie. Nawet jeśli twoje pytanie jest powiązane, powinieneś opublikować je jako osobne pytanie. Otrzymasz znacznie większą szansę na uzyskanie odpowiedzi w ten sposób.
Chris_O,