Эта проблема является классическим случаем, когда кто-то пытается выполнить ярлык при обновлении значения в сериализованной строке.Урок, который быстро усвоили, чтобы избежать этой головной боли, состоит в том, чтобы десериализовать ваши данные, изменить ваши значения, а затем повторно сериализовать их.проанализировать поврежденную сериализованную строку.Чтобы быть совершенно ясным, мой фрагмент будет обновлять только количество байтов / символов;если у вас есть сериализованная строка, которая повреждена каким-либо другим способом, это не будет решением проблемы.
Вот простой вызов preg_replace_callback()
, который захватывает только подстроку значения и безоговорочно заменяет все числа байтов в сериализованномстрока:
Код: ( Демо )
$corrupted_byte_counts = <<<STRING
a:1:{i:0;a:3:{s:7:"address";s:52:"Elågåresgude 41, 2200 Københamm N";s:12:"company_name";s:14:"Kaffe og Kluns";s:9:"telephone";s:0:"";}}
STRING;
$repaired = preg_replace_callback(
'/s:\d+:"(.*?)";/s',
function ($m) {
return 's:' . strlen($m[1]) . ":\"{$m[1]}\";";
},
$corrupted_byte_counts
);
echo "corrupted serialized array:\n$corrupted_byte_counts";
echo "\n---\n";
echo "repaired serialized array:\n$repaired";
echo "\n---\n";
print_r(unserialize($repaired));
Вывод:
corrupted serialized array:
a:1:{i:0;a:3:{s:7:"address";s:52:"Elågåresgude 41, 2200 Københamm N";s:12:"company_name";s:14:"Kaffe og Kluns";s:9:"telephone";s:0:"";}}
---
repaired serialized array:
a:1:{i:0;a:3:{s:7:"address";s:36:"Elågåresgude 41, 2200 Københamm N";s:12:"company_name";s:14:"Kaffe og Kluns";s:9:"telephone";s:0:"";}}
---
Array
(
[0] => Array
(
[address] => Elågåresgude 41, 2200 Københamm N
[company_name] => Kaffe og Kluns
[telephone] =>
)
)
Я даже пошел немного дальшедля устранения возможного дополнительного случая. Без реализации расширения шаблона в этой ссылке приведенный выше фрагмент будет работать по желанию для строк с:
- многобайтовыми символами
- символами новой строки
- двоеточия
- точки с запятой
- запятые
- одинарные кавычки
- двойные кавычки
Разрывается только когда строкадля сопоставления содержит ";
- в этом случае моя ссылка выше пытается обратиться к этой возможности.