Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm thế nào để sửa chữa một chuỗi được tuần tự hóa đã bị hỏng do độ dài đếm byte không chính xác?

unserialize() [function.unserialize]: Error at offset phải trả phí cho invalid serialization data do độ dài không hợp lệ

Khắc phục nhanh

Những gì bạn có thể làm là recalculating the length của các phần tử trong mảng được tuần tự hóa

Dữ liệu được tuần tự hóa hiện tại của bạn

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

Ví dụ mà không cần tính toán lại

var_dump(unserialize($data));

Đầu ra

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

Đang tính toán lại

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

Đầu ra

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)

Đề xuất .. Tôi

Thay vì sử dụng loại sửa chữa nhanh này ... tôi sẽ khuyên bạn nên cập nhật câu hỏi với

  • Cách bạn đang tuần tự hóa dữ liệu của mình

  • Bạn đang lưu nó như thế nào ..

================================CHỈNH SỬA 1 ===============================

Lỗi

Lỗi được tạo ra do sử dụng dấu ngoặc kép " thay vào đó là một trích dẫn duy nhất ' đó là lý do tại sao C:\fakepath\100.png đã được chuyển đổi thành C:fakepath100.jpg

Để sửa lỗi

Bạn cần thay đổi $h->vars['submitted_data'] Từ (Lưu ý rằng singe khá ' )

Thay thế

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

Với

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

Bộ lọc bổ sung

Bạn cũng có thể thêm bộ lọc đơn giản này trước khi gọi serialize

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

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

Nếu bạn có Ký tự UTF, bạn cũng có thể chạy

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

Cách phát hiện sự cố trong dữ liệu được tuần tự hóa trong tương lai

  findSerializeError ( $data1 ) ;

Đầu ra

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 Chức năng

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;
        }

    }

}

Cách tốt hơn để lưu vào Cơ sở dữ liệu

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Di chuyển MySQL sang PostgreSQL trên AWS RDS, Phần 4

  2. Cách theo dõi các chỉ số HAProxy với ClusterControl

  3. Cách tải hình ảnh lên cơ sở dữ liệu MySQL bằng mã PHP

  4. Cách thiết lập chuyển đổi dự phòng tự động cho cơ sở dữ liệu Moodle MySQL

  5. Cân nhắc về tính toàn vẹn và hiệu suất của dữ liệu trong sao chép bán đồng bộ MySQL