mysql - إصلاح البيانات التسلسلية كسر بسبب تحرير قاعدة بيانات ميسكل في محرر النص؟



wordpress mysqldump (4)

الخلفية: لقد قمت بتحميل * .sql احتياطية من قاعدة بيانات موقع وورد الخاص بي، واستبدال جميع مثيلات بادئة الجدول قاعدة البيانات القديمة مع واحد جديد (على سبيل المثال من wp_ الافتراضي إلى شيء مثل asdfghjkl_ ).

لقد تعلمت للتو أن وردبريس يستخدم سلاسل فب التسلسلية في قاعدة البيانات، وما فعلته سوف يكون قد عابث مع سلامة أطوال سلسلة متسلسلة.

الشيء هو، أنا حذف ملف النسخ الاحتياطي قبل أن تعلمت عن هذا (كما كان موقع الويب الخاص بي لا تزال تعمل بشكل جيد)، وتركيب عدد من الإضافات منذ ذلك الحين. لذلك، لا توجد طريقة يمكنني العودة إلى الوراء، ولذلك أود أن أعرف أمرين:

  1. كيف يمكنني إصلاح هذا، إذا كان ذلك ممكنا على الإطلاق؟

  2. أي نوع من المشاكل يمكن أن يسبب هذا السبب؟

(تشير هذه المقالة إلى أن مدونة وردبريس على سبيل المثال قد تفقد إعداداتها وأدواتها، ولكن يبدو أن هذا لم يحدث لي لأن جميع الإعدادات لمدونتي لا تزال سليمة، ولكن ليس لدي أي دليل على ما يمكن أو كسرها في الداخل، أو ما هي القضايا التي ستطرحها في المستقبل، ومن ثم فإن هذا السؤال).

https://src-bin.com


Answer #1

انتقل إلى هذه الصفحة: http://unserialize.onlinephpfunctions.com/

في هذه الصفحة يجب أن تشاهد هذا النموذج سلسلة متسلسلة: a:1:{s:4:"Test";s:17:"unserialize here!";} . خذ قطعة من it-- s:4:"Test"; . وهذا يعني "سلسلة"، 4 أحرف، ثم السلسلة الفعلية. أنا متأكد من أن ما قمت به هو تسبب عدد الأحرف الرقمية لتكون متزامنة مع السلسلة. لعب مع أداة على الموقع المذكور أعلاه وسوف ترى أن تحصل على خطأ إذا قمت بتغيير "اختبار" إلى "تيس"، على سبيل المثال.

ما عليك القيام به الحصول على تلك التهم حرف لتتناسب مع السلسلة الجديدة الخاصة بك. إذا لم تكن قد تلفت أي من التشفير الأخرى - إزالة القولون أو شيء-- التي يجب إصلاح المشكلة.



Answer #3

إذا كان الخطأ يرجع إلى طول السلاسل غير صحيحة (شيء رأيته بشكل متكرر)، ثم يجب أن تكون قادرا على التكيف مع هذا البرنامج النصي لإصلاحه:

foreach($strings as $key => $str)
{
    try {
        unserialize($str);
    } catch(exception $e) {
        preg_match_all('#s:([0-9]+):"([^;]+)"#',$str,$m);
        foreach($m[1] as $k => $len) {
            if($len != strlen($m[2][$k])) {
                $newstr='s:'.strlen($m[2][$k]).':"'.$m[2][$k].'"';
                echo "len mismatch: {$m[0][$k]}\n";
                echo "should be:    $newstr\n\n";
                $strings[$key] = str_replace($m[0][$k], $newstr, $str);
            }
        }
    }
}

Answer #4

وأنا أعلم أن هذا سؤال قديم، ولكن في وقت متأخر أفضل من أبدا، وأنا أفترض. لقد واجهت هذه المشكلة في الآونة الأخيرة، بعد وراثة قاعدة بيانات كان لها العثور / استبدال تنفيذها على البيانات التسلسلية. بعد ساعات طويلة من البحث، اكتشفت أن هذا كان بسبب التهم سلسلة كانت قبالة. لسوء الحظ، كان هناك الكثير من البيانات مع الكثير من الهروب والخطوط الجديدة، وأنا لم أكن أعرف كيفية الاعتماد في بعض الحالات وكان لدي الكثير من البيانات التي كنت بحاجة إلى شيء الآلي.

على طول الطريق، تعثرت عبر هذا السؤال، ساعدت وظيفة بنوبيرد في وضعي على الطريق الصحيح. لم يعمل رمز المثال الخاص به في استخدام الإنتاج على البيانات المعقدة، التي تحتوي على العديد من الأحرف الخاصة و هتمل، مع مستويات عميقة جدا من التعشيش، وأنها لم تعالج بشكل صحيح بعض الأحرف هرب والترميز. لذلك أنا تعديله قليلا وقضى ساعات لا تحصى من العمل من خلال البق إضافية للحصول على إصدار بلدي إلى "إصلاح" البيانات المتسلسلة.

// do some DB query here
while($res = db_fetch($qry)){
    $str = $res->data;
    $sCount=1; // don't try to count manually, which can be inaccurate; let serialize do its thing
    $newstring = unserialize($str);
    if(!$newstring) {
        preg_match_all('/s:([0-9]+):"(.*?)"(?=;)/su',$str,$m);
#           preg_match_all("/s:([0-9]+):(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")(?=;)/u",$str,$m); // alternate: almost works but leave quotes in $m[2] output
#           print_r($m); exit;
        foreach($m[1] as $k => $len) {
            /*** Possibly specific to my case: Spyropress Builder in WordPress ***/
            $m_clean = str_replace('\"','"',$m[2][$k]); // convert escaped double quotes so that HTML will render properly
            // if newline is present, it will output directly in the HTML
            // nl2br won't work here (must find literally; not with double quotes!)
            $m_clean = str_replace('\n', '<br />', $m_clean); 
            $m_clean = nl2br($m_clean);  // but we DO need to convert actual newlines also
            /*********************************************************************/
            if($sCount){
                $m_new = $m[0][$k].';'; // we must account for the missing semi-colon not captured in regex!
                // NOTE: If we don't flush the buffers, things like <img src="http://whatever" can be replaced with <img src="//whatever" and break the serialize count!!!                  
                ob_end_flush(); // not sure why this is necessary but cost me 5 hours!!
                $m_ser = serialize($m_clean);
                if($m_new != $m_ser) {
                    print "Replacing: $m_new\n";
                    print "With: $m_ser\n";
                    $str = str_replace($m_new, $m_ser, $str);
                }
            }
            else{
                $m_len = (strlen($m[2][$k]) - substr_count($m[2][$k],'\n'));
                if($len != $m_len) {
                    $newstr='s:'.$m_len.':"'.$m[2][$k].'"';
                    echo "Replacing: {$m[0][$k]}\n";
                    echo "With: $newstr\n\n";
                    $str = str_replace($m_new, $newstr, $str);
                }
            }
        }
        print_r($str); // this is your FIXED serialized data!! Yay!
    }
}

تفسير غريب الأطوار قليلا على التغييرات بلدي:

  • لقد وجدت أن محاولة الاعتماد مع رمز بينوبيرد كقاعدة كانت غير دقيقة جدا لمجموعة كبيرة من البيانات، لذلك انتهى بي الأمر فقط باستخدام تسلسل للتأكد من أن العد كان دقيقا.
  • أنا تجنب محاولة / الصيد لأنه، في حالتي، فإن المحاولة تنجح ولكن عاد للتو سلسلة فارغة. لذا، تحقق من البيانات الفارغة بدلا من ذلك.
  • حاولت العديد من ريجكس ولكن فقط وزارة الدفاع على بينوبيرد سوف التعامل بدقة جميع الحالات. على وجه التحديد، واضطررت إلى تعديل الجزء الذي فحص ل "؛" لأنه يتطابق مع كس مثل "ويدث: 100٪؛ هيت: 25px؛" وكسر الإخراج. لذلك، استخدمت وجهة نظر إيجابية لتتناسب فقط عندما "؛" كان خارج مجموعة من يقتبس مزدوجة.
  • كان حالتي الكثير من الخطوط الجديدة، هتمل، ونقلت مزدوجة الهروب، لذلك كان لي لإضافة كتلة لتنظيف ذلك.
  • كانت هناك حالتين غريبتين حيث سيتم استبدال البيانات بشكل غير صحيح من قبل المعكوس العادي ومن ثم سيحسب الرقم التسلسلي بشكل غير صحيح كذلك. وجدت نوثينغ على أي مواقع للمساعدة في هذا، وأخيرا يعتقد أنه قد تكون ذات صلة التخزين المؤقت أو شيء من هذا القبيل وحاول احمرار المخزن المؤقت الإخراج (ob_end_flush ())، التي عملت، شكرا الخير!

نأمل أن يساعد هذا شخص ... أخذت لي ما يقرب من 20 ساعة بما في ذلك البحث والتعامل مع قضايا غريبة! :)





mariadb