سؤال

كيف يمكنك تصحيح PHP النصوص ؟

أنا على علم الأساسية التصحيح مثل استخدام التقرير عن الخطأ.توقف التصحيح في PHPEclipse هو أيضا مفيدة جدا.

ما هو أفضل (حيث سريعة وسهلة) طريقة التصحيح في phpStorm أو أي IDE ؟

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

المحلول

محاولة الكسوف PDT الإعداد الكسوف البيئة التي لديها ميزات التصحيح كما ذكرت.القدرة على خطوة إلى رمز هو وسيلة أفضل بكثير لتصحيح ثم الأسلوب القديم من var_dump و الطباعة في نقاط مختلفة لنرى أين تدفق الخاص بك يذهب على نحو خاطئ.عندما فشل كل شيء آخر على الرغم من كل ما لدي هو SSH و همة ما زلت var_dump()/die() أن تجد فيها رمز يذهب الجنوب.

نصائح أخرى

يمكنك استخدام Firephp إضافة إلى الحرائق إلى تصحيح php في نفس بيئة جافا سكريبت.

أود أيضا أن استخدام Xdebug ذكر في وقت سابق عن التنميط php.

هذا هو بلدي قليلا تصحيح البيئة:

error_reporting(-1);
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_BAIL, 0);
assert_options(ASSERT_QUIET_EVAL, 0);
assert_options(ASSERT_CALLBACK, 'assert_callcack');
set_error_handler('error_handler');
set_exception_handler('exception_handler');
register_shutdown_function('shutdown_handler');

function assert_callcack($file, $line, $message) {
    throw new Customizable_Exception($message, null, $file, $line);
}

function error_handler($errno, $error, $file, $line, $vars) {
    if ($errno === 0 || ($errno & error_reporting()) === 0) {
        return;
    }

    throw new Customizable_Exception($error, $errno, $file, $line);
}

function exception_handler(Exception $e) {
    // Do what ever!
    echo '<pre>', print_r($e, true), '</pre>';
    exit;
}

function shutdown_handler() {
    try {
        if (null !== $error = error_get_last()) {
            throw new Customizable_Exception($error['message'], $error['type'], $error['file'], $error['line']);
        }
    } catch (Exception $e) {
        exception_handler($e);
    }
}

class Customizable_Exception extends Exception {
    public function __construct($message = null, $code = null, $file = null, $line = null) {
        if ($code === null) {
            parent::__construct($message);
        } else {
            parent::__construct($message, $code);
        }
        if ($file !== null) {
            $this->file = $file;
        }
        if ($line !== null) {
            $this->line = $line;
        }
    }
}

Xdebug و DBGp المساعد Notepad++ الثقيلة علة الصيد ، FirePHP عن اشياء.سريعة وقذرة ؟ لا شيء يدق dBug.

XDebug أمر ضروري من أجل التنمية.أنا تثبيته قبل أي ملحق آخر.يعطيك تتبعات المكدس على أي خطأ و يمكنك تمكين التنميط بسهولة.

لإلقاء نظرة سريعة على بنية بيانات الاستخدام var_dump().لا تستخدم print_r() لأن عليك أن تحيط بها مع <pre> وأنه فقط يطبع واحد فار في وقت واحد.

<?php var_dump(__FILE__, __LINE__, $_REQUEST); ?>

حقيقي التصحيح بيئة أفضل لقد وجدت هو Komodo IDE إلا أنه يكلف $$.

PhpEd هو جيد حقا.يمكنك خطوة الى/أكثر/من وظائف.يمكنك تشغيل المخصص رمز فحص المتغيرات تغيير المتغيرات.ومن المدهش.

1) استخدام print_r().في تيكستماتي لدي مقتطف من أجل 'قبل' والذي يوسع هذا:

echo "<pre>";
print_r();
echo "</pre>";

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

لقد استعملت زند ستوديو (5.5), مع زند منصة.أن يعطي السليم تصحيح نقاط/يخطو فوق رمز الخ ، على الرغم من أن في الأسعار.

في كل الصدق, مزيج من الطباعة print_r() لطباعة المتغيرات.وأنا أعلم أن الكثيرين يفضلون استخدام أساليب أكثر تقدما ولكن أجد هذا أسهل للاستخدام.

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

Xdebug, طريق ديريك Rethans, هو جيد جدا.اعتدت عليه منذ بعض الوقت وجدت أنه لم يكن من السهل جدا لتثبيت.بمجرد الانتهاء من ذلك, أنت لن تفهم كيف تمكنت من دون ذلك :-)

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

يمكنني استخدام Netbeans مع XDebug.التحقق من ذلك في موقعها الإلكتروني للمستندات على كيفية تكوين.http://php.netbeans.org/

يمكنني استخدام Netbeans مع XDebug ، من السهل XDebug فايرفوكس إضافة على

إضافة على أمر أساسي عند تصحيح MVC المشاريع ، لأن الطريقة العادية XDebug يعمل في Netbeans هو تسجيل dbug الدورة عبر عنوان url.مع إضافة على تثبيتها في فايرفوكس ، يمكنك تعيين الخاص بك Netbeans خصائص المشروع -> تشغيل Configuratuion -> خيارات متقدمة ثم اختر "لا تفتح متصفح الويب" يمكنك الآن تعيين نقاط لكسر وبدء جلسة عمل التصحيح مع الضغط على مفتاح Ctrl F5 كالمعتاد.فتح فايرفوكس وانقر بزر الماوس الأيمن على أيقونة في الزاوية السفلية اليمنى إلى بداية رصد نقاط.عندما رمز تصل إلى نقطة سوف تتوقف و يمكنك فحص الخاص بك متغير الدول استدعاء المكدس.

التخزين المؤقت الإخراج مفيد جدا إذا كنت لا تريد أن تصل الفوضى الإخراج الخاص بك.أفعل هذا في بطانة واحدة التي يمكنني التعليق/uncomment في

 ob_start();var_dump(); user_error(ob_get_contents()); ob_get_clean();

PhpEdit قد بنيت في المصحح ، ولكن عادة ما ينتهي باستخدام صدى();و print_r();الطريقة القديمة!!

بالنسبة حقا شجاع المشاكل التي من شأنها أن تستغرق وقتا طويلا جدا استخدام print_r/صدى لمعرفة استخدام IDE (PhpEd) التصحيح الميزة.على عكس غيرها من بيئات التطوير استخدمتها ، PhpEd يتطلب حد كبير في الإعداد.السبب الوحيد أنا لا تستخدم أي مشاكل واجهت أنه مؤلم بطيئة.أنا لست متأكدا من أن بطء محددة PhpEd أو أي php المصحح.PhpEd ليست مجانية ولكن أعتقد أنه يستخدم أحد مفتوح المصدر مصححات (مثل XDebug ذكر سابقا) على أي حال.فائدة مع PhpEd مرة أخرى هو أنه لا يتطلب الإعداد التي وجدت حقا مملة جدا في الماضي.

التصحيح اليدوي أسرع بشكل عام بالنسبة لي - var_dump() و debug_print_backtrace() هي كل الأدوات التي تحتاج إلى تسليح المنطق الخاص بك مع.

حسنا, إلى درجة أنه يعتمد على أين تسير الأمور في الجنوب.هذا أول شيء وأنا أحاول أن عزل ثم سوف تستخدم الصدى/print_r() عند الضرورة.

ملحوظة::أنتم تعلمون أنه يمكنك تمرير صحيح لأن الحجة الثانية أن print_r() وأنه سوف يعود الإخراج بدلا من الطباعة ؟ E. g.:

echo "<pre>".print_r($var, true)."</pre>";

أنا غالبا ما تستخدم للكيك عندما القضبان ليس ممكنا.لتصحيح الأخطاء عادة ما أجد error.log في مجلد tmp والذيل في المحطة مع الأمر...

tail -f app/tmp/logs/error.log

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

$this->log('xxxx');

هذا عادة ما يمكن أن تعطيك فكرة جيدة عن ما يجري/خطأ.

print_r( debug_backtrace() );

أو شيء من هذا القبيل :-)

Komodo IDE يعمل بشكل جيد مع xdebug ، حتى بالنسبة remore التصحيح.فإنه يحتاج الحد الأدنى من التكوين.كل ما عليك هو نسخة من php التي كومودو يمكن استخدامها محليا إلى الخطوة من خلال مدونة على نقطة.إذا كان لديك سيناريو المستوردة إلى كومودو المشروع, ثم يمكنك تعيين نقاط إيقاف مع الماوس-انقر فقط كيف سيكون وضعه داخل الكسوف من أجل التصحيح برنامج java.تصحيح الأخطاء عن بعد ومن الواضح أن أكثر صعبة للحصول على العمل بشكل صحيح ( قد يكون لديك خريطة remote url مع php النصي في مساحة العمل الخاصة بك ) من التصحيح المحلية الإعداد والتي من السهل جدا لتكوين إذا كنت على نظام ماك أو لينكس سطح المكتب.

Nusphere هو أيضا جيدة المصحح php nusphere

هناك العديد من PHP تقنيات التصحيح التي يمكن أن توفر لك ساعات لا تحصى عندما الترميز.فعال ولكن الأساسية التصحيح الأسلوب هو ببساطة بدوره على التقرير عن الخطأ.آخر قليلا أكثر تقدما الأسلوب ينطوي على استخدام طباعة البيانات التي يمكن أن تساعد في تحديد أكثر مراوغة البق عن طريق عرض ما يجري في الواقع على الشاشة.PHPeclipse هو الكسوف في المكونات التي يمكن تسليط الضوء على المشترك أخطاء في بناء الجملة و يمكن استخدامها جنبا إلى جنب مع مصحح أخطاء وضع نقاط التوقف.

display_errors = Off
error_reporting = E_ALL 
display_errors = On

وتستخدم أيضا

error_log();
console_log();

في بيئة الإنتاج ، تسجيل البيانات ذات الصلة إلى server سجل الأخطاء مع error_log().

يمكنني استخدام زند ستوديو الكسوف مع المدمج في المصحح.لا تزال بطيئة مقارنة مع التصحيح مع الكسوف pdt مع xdebug.نأمل أنها سوف يحل هذه المسائل ، تحسنت سرعة على الإصدارات الأخيرة ولكن لا يزال يخطو على الأشياء يأخذ 2-3 ثوان.زند فايرفوكس شريط الأدوات حقا يجعل الأمور سهلة (تصحيح الصفحة التالية الصفحة الحالية ، إلخ).كما أنه يوفر التعريف من شأنها أن المؤشر الخاص بك رمز و تقدم فطيرة الرسوم البيانية وقت التنفيذ ، وما إلى ذلك.

أكثر الأخطاء التي يمكن العثور عليها بسهولة ببساطة عن طريق var_dumping بعض المتغيرات الرئيسية ، ولكن من الواضح أنه يعتمد على أي نوع من التطبيق يمكنك تطوير.

أكثر خوارزميات معقدة خطوة/توقف/watch وظائف مفيدة جدا (إن لم يكن ضروريا)

PHP DBG

التفاعلية Stepthrough PHP المصحح تنفيذها باعتبارها SAPI وحدة التي يمكن أن تعطي تعطيك سيطرة كاملة على البيئة دون التأثير على وظيفة أو أداء التعليمات البرمجية الخاصة بك.وتهدف إلى أن تكون خفيفة الوزن وقوية وسهلة الاستخدام التصحيح منصة PHP 5.4+ و انه شحنها خارج مربع مع PHP 5.6.

ميزات تشمل ما يلي:

  • Stepthrough التصحيح
  • مرنة نقاط (أسلوب فئة, وظيفة, الملف:خط, عنوان, شفرة التشغيل)
  • سهولة الوصول إلى PHP مع المدمج في eval()
  • سهولة الوصول إلى حاليا تنفيذ التعليمات البرمجية
  • يوزرلاند API
  • SAPI الملحد - دمجها بسهولة
  • ملف التكوين PHP دعم
  • جيت سوبر جلوبل - مجموعة خاصة بك!!
  • اختياري readline الدعم مريحة محطة العملية
  • تصحيح الأخطاء عن بعد الدعم - المجمعة جافا GUI
  • عملية سهلة

انظر الصور:

PHP DBG - Stepthrough Debugging - screenshot

PHP DBG - Stepthrough Debugging - screenshot

الصفحة الرئيسية: http://phpdbg.com/

خطأ PHP - أفضل تقرير عن الخطأ لـ PHP

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

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

require('php_error.php');
\php_error\reportErrors();

ثم كل الأخطاء سوف تعطيك معلومات مثل تعقب رمز السياق الحجج وظيفة الخادم المتغيرات ، إلخ.على سبيل المثال:

PHP Error | Improve Error Reporting for PHP - screenshot of backtrace PHP Error | Improve Error Reporting for PHP - screenshot of backtrace PHP Error | Improve Error Reporting for PHP - screenshot of backtrace

وتشمل الميزات:

  • تافهة للاستخدام ، هو ملف واحد فقط
  • أخطاء عرضها في المتصفح العادي و ajaxy الطلبات
  • اياكس الطلبات مؤقتا ، مما يسمح لك تلقائيا إعادة تشغيلها
  • يجعل من الأخطاء صارمة قدر الإمكان (يشجع رمز الجودة و يميل إلى تحسين الأداء)
  • التعليمات البرمجية المتكررة في كل أنحاء تتبع المكدس
  • المزيد من المعلومات (مثل وظيفة كاملة التوقيعات)
  • إصلاح بعض رسائل الخطأ التي هي خاطئة تماما
  • تسليط الضوء على بناء الجملة
  • تبدو جميلة!
  • التخصيص
  • يدويا تشغيل وإيقاف
  • تشغيل أقسام محددة دون الإبلاغ عن الأخطاء
  • تجاهل الملفات مما يسمح لك لتجنب تسليط الضوء على رمز في تتبع المكدس
  • تطبيق الملفات ؛ هذه هي الأولوية عند خطأ الضربات!

الصفحة الرئيسية: http://phperror.net/

جيثب: https://github.com/JosephLenton/PHP-Error

الشوكة (مع إصلاحات إضافية): https://github.com/kenorb-contrib/PHP-Error

DTrace

إذا كان النظام الخاص بك يدعم DTrace ديناميكية تتبع (مثبتا بشكل افتراضي على نظام التشغيل OS X) و PHP الخاص بك هو المجمعة مع DTrace تحقيقات تمكين (--enable-dtrace) التي ينبغي أن تكون بشكل افتراضي, هذا الأمر يمكن أن تساعدك على تصحيح البرنامج النصي PHP مع أي وقت من الأوقات:

sudo dtrace -qn 'php*:::function-entry { printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }'

وذلك نظرا التالية الاسم المستعار قد أضيفت إلى rc الملفات (على سبيل المثال ~/.bashrc, ~/.bash_aliases):

alias trace-php='sudo dtrace -qn "php*:::function-entry { printf(\"%Y: PHP function-entry:\t%s%s%s() in %s:%d\n\", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }"'

قد أثر البرنامج النصي الخاص بك مع سهلة تذكر الاسم المستعار: trace-php.

هنا هو أكثر تقدما dtrace النصي مجرد حفظه إلى dtruss-php.d, جعله قابل للتنفيذ (chmod +x dtruss-php.d) وتشغيل:

#!/usr/sbin/dtrace -Zs
# See: https://github.com/kenorb/dtruss-lamp/blob/master/dtruss-php.d

#pragma D option quiet

php*:::compile-file-entry
{
    printf("%Y: PHP compile-file-entry:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1));
}

php*:::compile-file-return
{
    printf("%Y: PHP compile-file-return:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), basename(copyinstr(arg1)));
}

php*:::error
{
    printf("%Y: PHP error message:\t%s in %s:%d\n", walltimestamp, copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}

php*:::exception-caught
{
    printf("%Y: PHP exception-caught:\t%s\n", walltimestamp, copyinstr(arg0));
}

php*:::exception-thrown
{
    printf("%Y: PHP exception-thrown:\t%s\n", walltimestamp, copyinstr(arg0));
}

php*:::execute-entry
{
    printf("%Y: PHP execute-entry:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}

php*:::execute-return
{
    printf("%Y: PHP execute-return:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}

php*:::function-entry
{
    printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}

php*:::function-return
{
    printf("%Y: PHP function-return:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}

php*:::request-shutdown
{
    printf("%Y: PHP request-shutdown:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}

php*:::request-startup
{
    printf("%Y, PHP request-startup:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}

الصفحة الرئيسية: dtruss-مصباح في جيثب

هنا هو بسيط الاستخدام:

  1. تشغيل: sudo dtruss-php.d.
  2. في آخر محطة تشغيل: php -r "phpinfo();".

لاختبار ذلك ، يمكنك الذهاب إلى أي docroot مع index.php و تشغيل PHP مدمج الخادم عن طريق:

php -S localhost:8080

بعد ذلك يمكنك الوصول إلى الموقع في http://localhost:8080/ (أو اختيار أي ميناء مريحة بالنسبة لك).من هناك الوصول إلى بعض الصفحات لرؤية إخراج التتبع.

ملاحظة:Dtrace تتوفر على OS X بشكل افتراضي على لينكس ربما تحتاج dtrace4linux أو التحقق من بعض البدائل.

انظر: باستخدام PHP و DTrace في php.net


SystemTap

بدلا من ذلك تحقق SystemTap تتبع طريق تثبيت SystemTap المعاملة الخاصة والتفاضلية حزمة تطوير (مثلا ، yum install systemtap-sdt-devel).

هنا هو مثال على السكربت (all_probes.stp) لتتبع جميع الأساسية PHP ثابت نقاط التحقيق طوال مدة تشغيل البرنامج النصي PHP مع SystemTap:

probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
    printf("Probe compile__file__entry\n");
    printf("  compile_file %s\n", user_string($arg1));
    printf("  compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
    printf("Probe compile__file__return\n");
    printf("  compile_file %s\n", user_string($arg1));
    printf("  compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("error") {
    printf("Probe error\n");
    printf("  errormsg %s\n", user_string($arg1));
    printf("  request_file %s\n", user_string($arg2));
    printf("  lineno %d\n", $arg3);
}
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
    printf("Probe exception__caught\n");
    printf("  classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
    printf("Probe exception__thrown\n");
    printf("  classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
    printf("Probe execute__entry\n");
    printf("  request_file %s\n", user_string($arg1));
    printf("  lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("execute__return") {
    printf("Probe execute__return\n");
    printf("  request_file %s\n", user_string($arg1));
    printf("  lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("function__entry") {
    printf("Probe function__entry\n");
    printf("  function_name %s\n", user_string($arg1));
    printf("  request_file %s\n", user_string($arg2));
    printf("  lineno %d\n", $arg3);
    printf("  classname %s\n", user_string($arg4));
    printf("  scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("function__return") {
    printf("Probe function__return: %s\n", user_string($arg1));
    printf(" function_name %s\n", user_string($arg1));
    printf("  request_file %s\n", user_string($arg2));
    printf("  lineno %d\n", $arg3);
    printf("  classname %s\n", user_string($arg4));
    printf("  scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
    printf("Probe request__shutdown\n");
    printf("  file %s\n", user_string($arg1));
    printf("  request_uri %s\n", user_string($arg2));
    printf("  request_method %s\n", user_string($arg3));
}
probe process("sapi/cli/php").provider("php").mark("request__startup") {
    printf("Probe request__startup\n");
    printf("  file %s\n", user_string($arg1));
    printf("  request_uri %s\n", user_string($arg2));
    printf("  request_method %s\n", user_string($arg3));
}

الاستخدام:

stap -c 'sapi/cli/php test.php' all_probes.stp

انظر: باستخدام SystemTap مع PHP DTrace ثابت تحقيقات في php.net

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

echo '<pre>';
print_r($arrayOrObject);

أيضا var_dump($شيء) - وهذا مفيد جدا لمعرفة نوع subthings

اعتمادا على مسألة أحب مزيج من error_reporting(E_ALL) مختلطة مع صدى الاختبارات (للعثور على المخالف خط/الملف الخطأ حدث في شعر;أنت تعرف أنه ليس دائما خط/ملف php يقول لك أليس كذلك؟) ، IDE هدفين مطابقة (لحل "تحليل الخطأ:خطأ في بناء الجملة, unexpected $end" قضايا) ، print_r();الخروج ؛ مقالب (الحقيقي المبرمجين عرض المصدر ؛ p).

كنت أيضا لا يمكن أن تغلب phpdebug (التحقق من سورس) مع "memory_get_usage();" و "memory_get_peak_usage();" للعثور على المناطق المشكلة.

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

أ print_r هي سهلة الكتابة و هي مضمونة للعمل في أي إعداد.

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

يمكنك أيضا تجاوز المشترك استثناء فئة ، حيث أن هذا النوع من التصحيح هو شبه الآلي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top