Używam Hotaru CMS z wtyczką Image Upload, pojawia się ten błąd jeśli próbuję dołączyć obrazek do posta, w przeciwnym razie nie ma błędu:
unserialize () [function.unserialize]: Błąd przy przesunięciu
Obrażający kod (błąd wskazuje wiersz z **):
/**
* Retrieve submission step data
*
* @param $key - empty when setting
* @return bool
*/
public function loadSubmitData($h, $key = '')
{
// delete everything in this table older than 30 minutes:
$this->deleteTempData($h->db);
if (!$key) { return false; }
$cleanKey = preg_replace('/[^a-z0-9]+/','',$key);
if (strcmp($key,$cleanKey) != 0) {
return false;
} else {
$sql = "SELECT tempdata_value FROM " . TABLE_TEMPDATA . " WHERE tempdata_key = %s ORDER BY tempdata_updatedts DESC LIMIT 1";
$submitted_data = $h->db->get_var($h->db->prepare($sql, $key));
**if ($submitted_data) { return unserialize($submitted_data); } else { return false; }**
}
}
Dane z tabeli, zwróć uwagę, że na końcu bitu są informacje o obrazku, nie jestem ekspertem w PHP, więc zastanawiałem się, co wy możecie sobie pomyśleć
tempdata_value:
a:10:{s:16:"submit_editorial";b:0;s:15:"submit_orig_url";s:13:"www.bbc.co.uk";s:12:"submit_title";s:14:"No title found";s:14:"submit_content";s:12:"dnfsdkfjdfdf";s:15:"submit_category";i:2;s:11:"submit_tags";s:3:"bbc";s:9:"submit_id";b:0;s:16:"submit_subscribe";i:0;s:15:"submit_comments";s:4:"open";s:5:"image";s:19:"C:fakepath100.jpg";}
Edycja: myślę, że znalazłem bit serializacji ...
/**
* Save submission step data
*
* @return bool
*/
public function saveSubmitData($h)
{
// delete everything in this table older than 30 minutes:
$this->deleteTempData($h->db);
$sid = preg_replace('/[^a-z0-9]+/i', '', session_id());
$key = md5(microtime() . $sid . rand());
$sql = "INSERT INTO " . TABLE_TEMPDATA . " (tempdata_key, tempdata_value, tempdata_updateby) VALUES (%s,%s, %d)";
$h->db->query($h->db->prepare($sql, $key, serialize($h->vars['submitted_data']), $h->currentUser->id));
return $key;
}
php
mysql
serialization
content-management-system
user576820
źródło
źródło
@unserialize($product->des_txtmopscol);
@
nie jest usuwaniem błędów, jest to wyciszanie błędów - tak naprawdę nic nie "zostaje naprawione" tą techniką.Odpowiedzi:
unserialize() [function.unserialize]: Error at offset
byłoinvalid serialization data
należne z powodu nieprawidłowej długościSzybka naprawa
To, co możesz zrobić, to
recalculating the length
elementy w serializowanej tablicyBieżące dane serializowane
Przykład bez przeliczania
Wynik
Przeliczam
Wynik
Zalecenie .. I
Zamiast korzystać z tego rodzaju szybkiej poprawki ... radzę zaktualizować pytanie za pomocą
Jak serializujesz swoje dane
Jak to oszczędzasz ...
================================ EDYCJA 1 ================ ===============
Błąd
Błąd został wygenerowany z powodu użycia podwójnego cudzysłowu
"
zamiast pojedynczego cudzysłowu'
, dlategoC:\fakepath\100.png
został przekonwertowany naC:fakepath100.jpg
Aby naprawić błąd
Musisz zmienić
$h->vars['submitted_data']
From (Zwróć uwagę na singe'
)Zastąpić
Z
Dodatkowy filtr
Możesz również dodać ten prosty filtr przed wywołaniem serializacji
Jeśli masz znaki UTF, możesz również uruchomić
Jak wykryć problem w przyszłych serializowanych danych
Wynik
findSerializeError
FunkcjonowaćLepszy sposób zapisywania w bazie danych
źródło
findSerializeError
funkcji i znalazłem wiele błędów. Proszę spojrzeć na mój tematbase64
na artykule przed dodaniem go do bazy danych ... zachowałby znak nullNie mam wystarczającej reputacji, aby komentować, więc mam nadzieję, że widzą to osoby używające powyższej „poprawnej” odpowiedzi:
Od php 5.5 modyfikator / e w preg_replace () został całkowicie przestarzały, a powyższa preg_match zakończy się błędem. Dokumentacja php zaleca użycie preg_match_callback w jego miejsce.
Proszę znaleźć następujące rozwiązanie jako alternatywę dla powyższego proponowanego preg_match.
źródło
strlen()
a zatem powoduje nadmiarowe wywołania funkcji. Osobiście uważam, że dodanie warunku w tekście jest zbyt szczegółowe, ale ten fragment kodu robi dobre rzeczy z ważnych powodów.'!s:(\d+):"(.*?)";!s'
(z końcówką „s”, aby również wprowadzić nowe wiersze). Dzięki komentarzowi adilbo poniżej.Istnieje inny powód
unserialize()
niepowodzenia, ponieważ nieprawidłowo umieściłeś serializowane dane w bazie danych, patrz Oficjalne wyjaśnienie tutaj. Ponieważserialize()
zwraca dane binarne i zmienne php nie przejmują się metodami kodowania, więc umieszczenie ich w TEXT, VARCHAR () spowoduje ten błąd.Rozwiązanie: przechowuj serializowane dane w BLOB w swojej tabeli.
źródło
image
wartości bajtów . Twoja odpowiedź nie odnosi się do konkretnego pytania PO. Możesz przenieść swoje rady na: stackoverflow.com/q/5544749/2943403Szybka naprawa
Ponowne obliczanie długości elementów w serializowanej tablicy - ale nie używaj (preg_replace), jest to przestarzałe - lepiej użyj preg_replace_callback:
EDIT: Nowa wersja teraz nie tylko źle długość ale również określić line-breaks i liczyć poprawne znaki z aczent (dzięki mickmackusa )
źródło
Ten błąd jest spowodowany nieprawidłowym zestawem znaków.
Ustaw zestaw znaków po otwartym tagu:
I ustaw charset utf8 w swojej bazie danych:
źródło
image
wartość i nie zaktualizował liczby bajtów. O ile nie poinformowano inaczej, muszę założyć, że ta odpowiedź jest nieprawidłowa na pytanie PO.Możesz naprawić uszkodzony ciąg serializacji za pomocą następującej funkcji, z obsługą znaków wielobajtowych .
źródło
mb_strlen()
jest to niewłaściwe, ponieważserialize()
przechowuje liczbę bajtów, a nie liczbę znaków. Zmiana odpowiedzi na poprawną spowodowałaby tylko zbędne porady na stronie.public function unserializeKeySkills ($ string) {
źródło
trim()
każdy dopasowany podciąg. Już sam ten punkt uniemożliwia rekomendację tego rozwiązania. Co więcej, będzie się dławić znakami nowej linii i niepotrzebnie przechwytuje istniejącą liczbę bajtów, która i tak zostanie nadpisana. Wreszcie, jest to „odpowiedź oparta tylko na kodzie”, a tego typu odpowiedzi mają niewielką wartość, ponieważ nie przyczyniają się do edukacji / wspierania przyszłych naukowców.Nie możesz naprawić zepsutego ciągu serializacji za pomocą proponowanych wyrażeń regularnych:
Możesz naprawić uszkodzony ciąg serializacji za pomocą następującego wyrażenia regularnego:
Wynik
lub
źródło
że oficjalne docs mówi, powinien on powrócić fałszywe i ustawić e_notice
ale ponieważ wystąpił błąd, raportowanie błędów jest wyzwalane przez E_NOTICE
tutaj jest poprawka, która pozwala wykryć fałszywe zwrócone przez
unserialize
możesz rozważyć użycie kodowania / dekodowania base64
źródło
base64_encode
załatwił sprawę dla mnie. W moim przypadku przekazujemyserialize
dane d przez wiersz poleceń i wyglądało na to, że jakieś dziwne znaki uniemożliwiały mu prawidłowe działanie.base64_encode()
nie jest odpowiedzią na pytanie zadane przez PO. Pytanie / problem OP dotyczy w szczególności faktu, że (prawdopodobnie dotyczy to niewłaściwej zamiany podciągu w „końcowym elemencie tablicy” serializowanego ciągu), że w serializowanym ciągu jest nieprawidłowa liczba bajtów. Prosimy o publikowanie tylko odpowiedzi, które dotyczą bezpośrednio zadanego pytania.Uszkodzenie w tym pytaniu jest izolowane do pojedynczego podciągu na końcu serializowanego ciągu, który prawdopodobnie został ręcznie zastąpiony przez kogoś, kto leniwie chciał zaktualizować
image
nazwę pliku. Fakt ten będzie widoczny w moim linku demonstracyjnym poniżej, korzystając z opublikowanych danych PO - krótko mówiąc,C:fakepath100.jpg
nie ma długości19
, a powinno17
.Ponieważ uszkodzenie zserializowanego ciągu jest ograniczone do nieprawidłowej liczby bajtów / znaków, poniższe czynności wykonają dobrą robotę aktualizacji uszkodzonego ciągu z poprawną wartością liczby bajtów.
Poniższe zastąpienie oparte na wyrażeniach regularnych będzie skuteczne tylko w naprawianiu liczby bajtów, nic więcej.
Wygląda na to, że wiele wcześniejszych postów po prostu kopiowało i wklejało wzorzec regex od kogoś innego. Nie ma powodu, aby przechwytywać liczbę potencjalnie uszkodzonych bajtów, jeśli nie będzie ona używana w zamianie. Ponadto dodanie
s
modyfikatora wzorca jest rozsądnym włączeniem w przypadku, gdy wartość ciągu zawiera znaki nowej linii / powrotu.* Dla tych, którzy nie są świadomi traktowania znaków wielobajtowych podczas serializacji, nie wolno ich używać
mb_strlen()
w niestandardowym wywołaniu zwrotnym, ponieważ jest to liczba bajtów, która jest przechowywana, a nie liczba znaków , zobacz moje dane wyjściowe ...Kod: ( Demo z danymi OP ) ( Demo z dowolnymi przykładowymi danymi ) ( Demo z zamianą warunków )
Wynik:
Jedna noga w dół króliczej nory ... Powyższe działa dobrze, nawet jeśli w wartości ciągu występują podwójne cudzysłowy, ale jeśli wartość ciągu zawiera
";
lub jakieś inne wyrażanie małpią, musisz pójść trochę dalej i zaimplementować „lookarounds”. Mój nowy wzórsprawdza, czy prowadzenie
s
to:;
i sprawdza, czy
";
:}
lubs:
lubi:
Nie testowałem wszystkich możliwości; w rzeczywistości jestem stosunkowo nieobeznany ze wszystkimi możliwościami serializowanego ciągu, ponieważ nigdy nie decyduję się na pracę z serializowanymi danymi - zawsze json w nowoczesnych aplikacjach. Jeśli są dodatkowe możliwe znaki początkowe lub końcowe, zostaw komentarz, a ja rozszerzę wyszukiwania.
Rozszerzony fragment: ( Demo )
Wynik:
źródło
Będziesz musiał zmienić typ sortowania na,
utf8_unicode_ci
a problem zostanie rozwiązany.źródło
utf8_unicode_ci
? Mam co do tego wątpliwości.W moim przypadku przechowywałem zserializowane dane w
BLOB
polu bazy danych MySQL, które najwyraźniej nie były wystarczająco duże, aby pomieścić całą wartość i ją obcięłem. Takiego sznurka oczywiście nie można odserializować.Po przekonwertowaniu tego pola
MEDIUMBLOB
na problem zniknął. Może być również konieczne przełączenie opcji tabeliROW_FORMAT
naDYNAMIC
lubCOMPRESSED
.źródło
TEXT
polem i jako takie obcięte do 65kb.Po wypróbowaniu kilku rzeczy na tej stronie bez powodzenia zajrzałem do źródła strony i zauważyłem, że wszystkie cudzysłowy w serializowanym ciągu zostały zastąpione encjami html. Dekodowanie tych jednostek pomaga uniknąć dużego bólu głowy:
źródło
Oto narzędzie online do naprawy uszkodzonego serializowanego ciągu.
Chciałbym dodać, że to dzieje się głównie ze względu na wyszukiwanie i zamiana odbywa się na DB i danych serializacji ( specjalnie
key length
) nie zostanie uaktualnione zgodnie Replace i który powoduje, że „korupcja”.Niemniej jednak powyższe narzędzie używa następującej logiki do naprawiania danych serializacji ( skopiowane stąd ).
źródło
Inną przyczyną tego problemu może być kolumna tabeli sesji „ładunku”. Jeśli masz ogromne dane dotyczące sesji, kolumna tekstowa nie wystarczy. Będziesz potrzebował MEDIUMTEXT lub nawet LONGTEXT.
źródło