هل يمكنني اكتشاف تحذيرات MySQL والتعامل معها باستخدام PHP؟

StackOverflow https://stackoverflow.com/questions/47589

سؤال

أنا أتعامل مع جدول MySQL الذي يحدد عمود JobName على أنه فريد.إذا حاول شخص ما حفظ مهمة جديدة في قاعدة البيانات باستخدام JobName الموجود بالفعل في قاعدة البيانات، فسيقوم MySQL بإصدار تحذير.

أود أن أكون قادرًا على اكتشاف هذا التحذير، تمامًا مثل الخطأ، في برنامج PHP النصي الخاص بي والتعامل معه بشكل مناسب.من الناحية المثالية، أود أن أعرف نوع التحذير الذي أصدرته MySQL حتى أتمكن من تفرع الكود للتعامل معه.

هل هذا ممكن؟إذا لم يكن الأمر كذلك، فهل يرجع ذلك إلى أن MySQL لا تملك هذه القدرة، أو PHP لا تملك هذه القدرة، أو كليهما؟

هل كانت مفيدة؟

المحلول

لكي يتم "وضع علامة" على التحذيرات إلى PHP محليًا، سيتطلب الأمر إجراء تغييرات على برنامج تشغيل mysql/mysqli، وهو ما يتجاوز بوضوح نطاق هذا السؤال.بدلاً من ذلك، سيتعين عليك التحقق بشكل أساسي من كل استعلام تجريه في قاعدة البيانات بحثًا عن التحذيرات:

$warningCountResult = mysql_query("SELECT @@warning_count");
if ($warningCountResult) {
    $warningCount = mysql_fetch_row($warningCountResult );
    if ($warningCount[0] > 0) {
        //Have warnings
        $warningDetailResult = mysql_query("SHOW WARNINGS");
        if ($warningDetailResult ) {
            while ($warning = mysql_fetch_assoc(warningDetailResult) {
                //Process it
            }
        }
    }//Else no warnings
}

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

كمرجع، MySQL تظهر التحذيرات

بالطبع، يمكنك الاستغناء عن الاستعلام الأولي لـ SELECT @@warning_count, ، مما سيوفر لك استعلامًا لكل عملية تنفيذ، لكنني قمت بتضمينه من أجل الاكتمال المتحذلق.

نصائح أخرى

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

يبدو أن هذا هو رقم الخطأ الذي تبحث عنه:

خطأ:1169 سكلستات:23000 (ER_DUP_UNIQUE)

رسالة:لا يمكن الكتابة، بسبب قيد فريد، إلى الجدول '%s'

ini_set('mysql.trace_mode', 1)

قد يكون ما تبحث عنه.

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

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

اعتمادًا على عدد أسماء الوظائف، يمكنك إرسال الأسماء إلى العرض الذي يحتوي على النموذج واستخدام جافا سكريبت لمعرفة الاستخدام الذي تم استخدامه.

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

تم التحديث لإزالة الأشياء المتعلقة بوظائف errno والتي أدرك الآن أنها لا تنطبق على موقفك...

شيء واحد في MySQL يجب الحذر منه UPDATE صياغات: mysqli_affected_rows() سوف يعود الصفر حتى لو كان WHERE جملة متطابقة مع الصفوف، ولكن SET جملة لم تغير في الواقع قيم البيانات.أذكر هذا فقط لأن هذا السلوك تسبب في حدوث خطأ في النظام الذي نظرت إليه ذات مرة - استخدم المبرمج قيمة الإرجاع هذه للتحقق من الأخطاء بعد التحديث، بافتراض أن الصفر يعني حدوث خطأ ما.هذا يعني فقط أن المستخدم لم يغير أي قيم موجودة قبل النقر على زر التحديث.

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

يمكنك اكتشاف انتهاكات المفاتيح الفريدة باستخدام بيان mysqli خطأ رقم.تُرجع عبارة mysqli الخطأ 1062، وهو ER_DUP_ENTRY.يمكنك البحث عن الخطأ 1062 وطباعة رسالة الخطأ المناسبة.إذا كنت تريد طباعة العمود الخاص بك (jobName) أيضًا كجزء من رسالة الخطأ، فيجب عليك تحليل سلسلة خطأ البيان.

  if($stmt = $mysqli->prepare($sql)){
            $stmt->bind_param("sss",
            $name,
            $identKey,
            $domain);


            $stmt->execute();
            if($mysqli->affected_rows != 1)  {
                        //This will return errorno 1062
                trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR);
                exit(1);
            }
            $stmt->close();
        } else {

            trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR);
        }

من الممكن الحصول على التحذيرات، وبطريقة أكثر كفاءة باستخدام mysqli مقارنة بـ mysql.

هنا هو الكود المقترح في الدليل صفحة على php.net للخاصية mysqli->warning_count:

$mysqli->query($query);

if ($mysqli->warning_count) {
    if ($result = $mysqli->query("SHOW WARNINGS")) {
        $row = $result->fetch_row();
        printf("%s (%d): %s\n", $row[0], $row[1], $row[2]);
        $result->close();
    }
}

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

مثال:

 // this suppresses warnings that might result if there is no field titled "field" in the result
 $field_value = @mysql_result($result, 0, "field");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top