De ce pierd date din widget-urile text în timpul importului bazei de date?
Am creat un site în WordPress pe mașina noastră de dezvoltare. În tema pe care o folosim există numeroase zone de widget-uri pentru afișarea textului (sidebar și pagina principală). Am folosit widget-uri simple de Text în toate aceste zone pentru a pune informațiile noastre de afișare.
Când am migrat site-ul în producție, am folosit plugin-ul WP-DB-Backup pentru a face o copie a bazei de date. Apoi am editat fișierul .sql rezultat pentru a actualiza toate căile fișierelor și referințele URL pentru a indica către site-ul nostru de producție.
După crearea bazei de date, a site-ului web și copierea tuturor fișierelor pe site-ul de producție, rulez fișierul .sql din linia de comandă mysql pentru a importa datele în noua bază de date.
Cu toate acestea, când accesez site-ul de producție, unele texte apar și altele nu. Când mă uit în secțiunea de widget-uri a site-ului, widget-urile text lipsesc din unele zone de widget-uri. Widget-urile text nu sunt vizibile nici măcar în zona "Widget-uri Inactive", pur și simplu nu există.
Am încercat să repet procesul folosind plugin-ul BackWPup, observând că sintaxa SQL este diferită când exportă baza de date.
De ce pierd date din widget-urile text în timpul importului?

Aici este problema ta:
Apoi am editat fișierul .sql rezultat pentru a actualiza toate căile de fișiere și referințele URL să indice spre site-ul nostru de producție.
Nu poți face asta. WordPress stochează multe opțiuni ca "date serializate", care conțin atât conținutul string al lucrurilor cât și lungimea lor. Deci, când modifici URL-ul și lungimea se schimbă, atunci datele serializate nu mai sunt corecte, iar PHP le respinge.
Problema pe termen lung este că, practic, o faci greșit. Dacă configurezi un site de dezvoltare care va avea datele migrate, atunci acesta ar trebui să aibă exact același URL ca site-ul de producție de la început. Poți edita manual fișierul HOSTS pentru a da acelui domeniu de producție (cum ar fi exemplu.com) o adresă IP diferită (cum ar fi 127.0.0.1) și astfel URL-ul "de producție" va deveni site-ul de dezvoltare, doar pentru tine. Apoi poți crea datele, linkurile și orice altceva folosind acel URL de producție, iar când migrezi datele, nimic din ele nu trebuie modificat.
Pe termen scurt, totuși, nu folosi un simplu înlocuire text în fișierul SQL. După cum ai descoperit, asta strică lucrurile.
Și deși ezit să sugerez asta, există o modalitate de a modifica codul de bază al WordPress pentru a gestiona aceste serializări stricate. Trebuie să modifici fișierul wp-includes/functions.php și să schimbi funcția maybe_unserialize() în asta:
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]); }
Aceasta NU este o soluție viabilă pe termen lung. Ar trebui folosită doar pentru a te pune pe picioare acum. Pe termen lung, trebuie să îți repari procesul de dezvoltare astfel încât să nu mai fie nevoie de astfel de modificări de URL de la bun început.

@Otto răspuns excelent. O întrebare rapidă: dacă modific o tabelă non-serializată blob/text ca wp_posts în afara MySQL, va afecta datele serializate din wp_post_meta sau wp_options? Am avut aceeași problemă cu widget-ul de text, dar nu am atins wp_options, am modificat doar wp_posts.

Uau, nu mi-am dat seama că asta se întâmpla cu datele, dar are sens perfect! Mulțumesc mult!

Aceasta NU este o soluție viabilă pe termen lung - nici măcar pe termen scurt.

Interesant; cum se poate edita fișierul hosts pentru a direcționa example.com către localhost 127.0.0.1?

Dacă dorești să faci asta pe calculatorul tău local, pur și simplu găsește fișierul hosts și adaugă o intrare acolo (verifică superuser.com pentru detalii specifice sistemului tău de operare). Altfel, poți cere administratorului de Operațiuni sau Rețea să adauge o intrare la controlerul de domeniu.

O altă soluție pe care o folosesc unii este să configureze sistemul de dezvoltare cu un nume de domeniu "example.dev" în loc de "example.com". Astfel, lungimile șirurilor nu se schimbă când sunt mutate în producție. Eu prefer metoda cu fișierul HOSTS.

@songdogtech - Adaugă o nouă linie în fișierul hosts 127.0.0.1 example.com
, fișierul se află în C:\WINDOWS\system32\drivers\etc\hosts
..(presupunând calea de instalare implicită). Notă: Xampp și aplicații similare adaugă de obicei host-uri virtuale în acest fișier, așa că probabil vei avea deja câteva intrări acolo.

Aceasta nu este cu adevărat o soluție, ci mai degrabă un hack! Există și scenarii în care nu poți modifica fișierul hosts. De exemplu, în spatele unui proxy corporativ sau dacă ai https în producție și http în dezvoltare.

2016 și WordPress încă salvează date serializate în baza de date. Premiul pentru cel mai faimos cod prost
nu trebuie să caute mai departe.

MULȚUMESC!!! Bun punct și hack excelent. În general, folosesc acest hack pentru a recupera toate datele și apoi actualizez setările existente din nou, iar când elimin acest cod, funcționează perfect.

Pentru a rezolva această problemă, folosesc întotdeauna instrumentul WordPress Serialized Search & Replace disponibil aici. Funcționează perfect fără nicio problemă. Îl folosesc de mult timp pentru toate nevoile de migrare a site-urilor. Acest instrument se ocupă de problemele legate de migrarea bazei de date de la mediul de dezvoltare la cel de producție.
https://interconnectit.com/search-and-replace-for-wordpress-databases/

Da, folosesc acest script de ani de zile și îl recomand cu mare încredere

A funcționat pentru mine în majoritatea cazurilor. Dar săptămâna aceasta când am înlocuit http://localhost/Me/site_name
cu http://site.dev
(de la un localhost la altul) folosind versiunea 3.0.0, în mod ciudat am pierdut pozițiile widget-urilor și ale meniurilor. Deci probabil această problemă este legată și de lungimea șirului.

Am folosit... dar nu am întâlnit această situație până acum. Poți să descarci o versiune mai veche a acestui script și să încerci din nou cu ea. Încearcă să înlocuiești localhost/Me/site_name
cu site.dev
.

URL-ul s-a schimbat (acum este https în loc de http) : https://interconnectit.com/products/search-and-replace-for-wordpress-databases/

Script excelent. Am duplicat o bază de date MySQL din PHPMyAdmin de la una veche la una nouă - fără nicio modificare a URL-urilor -, apoi m-am dus în folderul noului site unde erau fișierele proaspete WordPress (împreună cu un fișier wp-config.php corect, cu noile credențiale pentru baza de date), am adăugat scriptul, iar acesta s-a ocupat de toate modificările necesare. Datele serializate sunt actualizate împreună cu URL-urile normale. Simplu și rapid! Foarte recomandat. Important: nu uitați să eliminați scriptul după utilizare deoarece are acces la detaliile bazei de date!

Răspunsul lui Otto este perfect. Am descoperit și eu asta pe pielea mea.
Totuși, am reușit să ocolesc problema folosind un script interesant de pe http://spectacu.la/search-and-replace-for-wordpress-databases/
Pentru a migra WordPress-ul tău pe un nou URL sau nume de domeniu, urmează pașii următori:
- Fă un dump al bazei de date (de exemplu folosind phpmyadmin) din WordPress-ul existent
- Restaurează dump-ul așa cum este (fără modificări) în noua locație
- Dezarhivează scriptul de pe spectacu.la în folderul root al WordPress-ului (nu este un plugin...)
- Rulează scriptul pe noul site accesându-l din browser, de exemplu http://new-website.url/searchreplacedb.php
- Nu uita să ștergi scriptul din folderul root al noului WordPress

Știu că este cam veche, dar unde ar trebui să specific noul nume al bazei de date dacă restaurăm dump-ul așa cum este? Nu ar trebui măcar să pun noul nume al bazei de date în al doilea pas? Mulțumesc pentru această informație.

Nu sunt sigur că înțeleg pe deplin întrebarea ta. Restaurarea bazei de date poate fi făcută cu instrumente precum phpmyadmin și poți să îi dai un nume nou sau să folosești vechiul nume. Scriptul pe care l-am menționat schimbă doar textul din interiorul bazei de date după ce a fost deja restaurată.

Bună Yoav, mulțumesc pentru răspuns, mă refer la faptul că atunci când export o bază de date, de obicei schimb numele bazei de date cu cel nou și modific link-urile de domeniu. Având în vedere acest lucru, în pasul tău numărul doi spui să restaurez dump-ul așa cum este fără modificări, voiam doar să știu dacă asta înseamnă literalmente sau trebuie să schimb măcar numele bazei de date. Știu că poate fi o întrebare simplă, dar sunt puțin pierdut, mulțumesc din nou pentru răspuns.

Nu știu cum îți salvezi baza de date, dar dacă folosești instrumentul de 'export' din phpmyadmin, atunci nu contează care este numele bazei de date. Poți folosi exportul și să îl imporți înapoi în orice altă bază de date. În general, referitor la al doilea punct, cred că este în regulă să schimbi numele bazei de date.

OP a fost prea entuziast în înlocuirea globală în fișierul de export al bazei de date, ajungând să modifice aparițiile "wp_" în unele dintre datele serializate. Soluția este să fii mai precaut în înlocuirea globală prin includerea backtick-ului în expresia regulată, apoi actualizând manual cheile rămase în baza de date după import.
Dacă migrezi și schimbi prefixul, și preferi o abordare mai manuală, urmează pașii următori (aceștia abordează doar preocupările OP-ului și nu se ocupă de actualizarea URL-ului site-ului)
- Fă o copie de siguranță și mută fișierul SQL de export al bazei de date în noul mediu (exemplul meu presupune un nume de fișier backup_AAAA-LL-ZZ.sql)
- Realizează o înlocuire globală în fișierul SQL pentru a schimba numele tabelelor folosind noul tău prefix (ÎNAINTE de a importa fișierul SQL!). O metodă de a face asta ar fi să folosești o linie de comandă Perl precum: perl -p -i.bak -e "s/`wp_/`prefixulmeu_/g" backup_AAAA-LL-ZZ.sql
- Importă datele SQL în baza de date
- Actualizează orice chei din _options care conțin prefixul codat: update prefixulmeu_options set option_name = concat('prefixulmeu_',substr(option_name,4)) where option_name like 'wp_%'
- Actualizează orice chei din _user_meta care conțin prefixul codat: update prefixulmeu_usermeta set meta_key = concat('prefixulmeu_',substr(meta_key,4)) where meta_key like 'wp_%'

Am folosit pluginul WP Migrate, care înlocuiește căile http și folderele. Am avut o singură problemă la import, dar am rezolvat-o adăugând următoarele linii în partea de sus a fișierului sql generat:
/*!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 */;
Am încercat și cu instrumentul Search And Replace (v2.1) recomandat de @Yoav, dar tot mi-a stricat datele serializate.

Salut Ricardo, Bine ai venit pe WordPress Answers! Zona în care ai postat este rezervată pentru răspunsuri la întrebarea inițială. Chiar dacă întrebarea ta este legată, ar trebui să o postezi ca o întrebare separată. Vei avea o șansă mult mai mare să primești un răspuns în acest fel.
