sql >> Database >  >> RDS >> Mysql

Hoe een geserialiseerde string te repareren die is beschadigd door een onjuiste byte-tellingslengte?

unserialize() [function.unserialize]: Error at offset was verschuldigd aan invalid serialization data vanwege ongeldige lengte

Snelle oplossing

Wat je kunt doen is recalculating the length van de elementen in geserialiseerde array

Uw huidige geserialiseerde gegevens

$data = '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";}';

Voorbeeld zonder herberekening

var_dump(unserialize($data));

Uitgang

Notice: unserialize() [function.unserialize]: Error at offset 337 of 338 bytes

Herberekenen

$data = preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", $data);
var_dump(unserialize($data));

Uitgang

array
  'submit_editorial' => boolean false
  'submit_orig_url' => string 'www.bbc.co.uk' (length=13)
  'submit_title' => string 'No title found' (length=14)
  'submit_content' => string 'dnfsdkfjdfdf' (length=12)
  'submit_category' => int 2
  'submit_tags' => string 'bbc' (length=3)
  'submit_id' => boolean false
  'submit_subscribe' => int 0
  'submit_comments' => string 'open' (length=4)
  'image' => string 'C:fakepath100.jpg' (length=17)

Aanbeveling .. Ik

In plaats van dit soort snelle oplossing te gebruiken ... raad ik u aan de vraag bij te werken met

  • Hoe u uw gegevens serialiseert

  • Hoe je het opslaat ..

================================BEWERK 1 ===============================

De fout

De fout is gegenereerd vanwege het gebruik van dubbele aanhalingstekens " in plaats daarvan enkel aanhalingsteken ' daarom C:\fakepath\100.png is geconverteerd naar C:fakepath100.jpg

Om de fout te herstellen

U moet $h->vars['submitted_data'] . wijzigen Van (Let op de singe nogal ' )

Vervangen

 $h->vars['submitted_data']['image'] = "C:\fakepath\100.png" ;

Met

 $h->vars['submitted_data']['image'] = 'C:\fakepath\100.png' ;

Extra filter

U kunt dit eenvoudige filter ook toevoegen voordat u serialize aanroept

function satitize(&$value, $key)
{
    $value = addslashes($value);
}

array_walk($h->vars['submitted_data'], "satitize");

Als u UTF-tekens heeft, kunt u ook

. uitvoeren
 $h->vars['submitted_data'] = array_map("utf8_encode",$h->vars['submitted_data']);

Hoe het probleem in toekomstige geserialiseerde gegevens te detecteren

  findSerializeError ( $data1 ) ;

Uitgang

Diffrence 9 != 7
    -> ORD number 57 != 55
    -> Line Number = 315
    -> Section Data1  = pen";s:5:"image";s:19:"C:fakepath100.jpg
    -> Section Data2  = pen";s:5:"image";s:17:"C:fakepath100.jpg
                                            ^------- The Error (Element Length)

findSerializeError Functie

function findSerializeError($data1) {
    echo "<pre>";
    $data2 = preg_replace ( '!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'",$data1 );
    $max = (strlen ( $data1 ) > strlen ( $data2 )) ? strlen ( $data1 ) : strlen ( $data2 );

    echo $data1 . PHP_EOL;
    echo $data2 . PHP_EOL;

    for($i = 0; $i < $max; $i ++) {

        if (@$data1 {$i} !== @$data2 {$i}) {

            echo "Diffrence ", @$data1 {$i}, " != ", @$data2 {$i}, PHP_EOL;
            echo "\t-> ORD number ", ord ( @$data1 {$i} ), " != ", ord ( @$data2 {$i} ), PHP_EOL;
            echo "\t-> Line Number = $i" . PHP_EOL;

            $start = ($i - 20);
            $start = ($start < 0) ? 0 : $start;
            $length = 40;

            $point = $max - $i;
            if ($point < 20) {
                $rlength = 1;
                $rpoint = - $point;
            } else {
                $rpoint = $length - 20;
                $rlength = 1;
            }

            echo "\t-> Section Data1  = ", substr_replace ( substr ( $data1, $start, $length ), "<b style=\"color:green\">{$data1 {$i}}</b>", $rpoint, $rlength ), PHP_EOL;
            echo "\t-> Section Data2  = ", substr_replace ( substr ( $data2, $start, $length ), "<b style=\"color:red\">{$data2 {$i}}</b>", $rpoint, $rlength ), PHP_EOL;
        }

    }

}

Een betere manier om op te slaan in de database

$toDatabse = base64_encode(serialize($data));  // Save to database
$fromDatabase = unserialize(base64_decode($data)); //Getting Save Format 


  1. Oplossing voor:Store update-, insert- of delete-instructie beïnvloedde een onverwacht aantal rijen (0)

  2. Hoe krijg ik ASCII-waarde in Oracle?

  3. HikariCP - verbinding is niet beschikbaar

  4. PHP date() formaat bij het invoegen in datetime in MySQL