For people that struggle with this I made this code that fixes seralization after migration and SQL name change to the new domain.
- You have to create a file in your root called fix-serialization.php
- Add this code in the file (please change your site name in the $needle to your site name)
<?php
require __DIR__ . '/wp-load.php';
if ( ! current_user_can('manage_options') ) { wp_die('Forbidden'); }
global $wpdb;
$needle = 'yoursitehere.com';
function fix_serialized_lengths($str) {
return preg_replace_callback(
'/s:(\d+):"(.*?)";/s',
function($m) {
$len = strlen($m[2]);
return 's:' . $len . ':"' . $m[2] . '";';
},
$str
);
}
function try_repair_value($raw) {
$un = @unserialize($raw);
if ($un !== false || $raw === 'b:0;') {
return null;
}
$fixed = fix_serialized_lengths($raw);
$un2 = @unserialize($fixed);
if ($un2 !== false || $fixed === 'b:0;') {
return serialize($un2);
}
return null;
}
$targets = [
['table' => $wpdb->options, 'id' => 'option_id', 'col' => 'option_value'],
['table' => $wpdb->postmeta, 'id' => 'meta_id', 'col' => 'meta_value'],
['table' => $wpdb->usermeta, 'id' => 'umeta_id', 'col' => 'meta_value'],
['table' => $wpdb->termmeta, 'id' => 'meta_id', 'col' => 'meta_value'],
['table' => $wpdb->commentmeta,'id'=> 'meta_id', 'col' => 'meta_value'],
];
$total_scanned = 0;
$total_fixed = 0;
foreach ($targets as $t) {
$table = $t['table'];
$idcol = $t['id'];
$valcol= $t['col'];
$like = '%' . $wpdb->esc_like($needle) . '%';
$ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT {$idcol} FROM {$table} WHERE {$valcol} LIKE %s AND {$valcol} REGEXP '^[aObisCd]:'",
$like
)
);
if (!$ids) continue;
foreach ($ids as $id) {
$row = $wpdb->get_row(
$wpdb->prepare("SELECT {$valcol} AS v FROM {$table} WHERE {$idcol} = %d", $id)
);
if (!isset($row->v)) continue;
$total_scanned++;
$newv = try_repair_value($row->v);
if ($newv !== null && $newv !== $row->v) {
$updated = $wpdb->update(
$table,
[$valcol => $newv],
[$idcol => $id],
['%s'],
['%d']
);
if ($updated !== false) {
$total_fixed++;
}
}
}
}
echo "<pre>";
echo "Scanned rows: {$total_scanned}\n";
echo "Repaired rows: {$total_fixed}\n";
echo "Done\n";
echo "</pre>";
- Login in your site
- Run the script by visiting [yoursitename.com]/fix-serialization.php
- Done it should work. (The script returns the amount of fixes it makes.)
I don’t know why Briks doesn’t just add a button in settings that just does this but whatever.
Please be careful with the domain name and make sure it is the correct one in the php code but also in step 4.