كيف تختلف عوامل مقارنة المساواة (== يساوي المزدوج) والهوية (=== يساوي الثلاثي)؟

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

سؤال

ماهو الفرق بين == و ===?

  • كيف بالضبط فضفاضة == عمل المقارنة؟
  • كيف بالضبط صارمة === عمل المقارنة؟

ماذا ستكون بعض الأمثلة المفيدة؟

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

المحلول

الفرق بين == و ===

الفرق بين فضفاضة == عامل متساو وصارم === تم شرح عامل التشغيل المتطابق تمامًا في يدوي:

عوامل المقارنة

┌──────────┬───────────┬───────────────────────────────────────────────────────────┐
│ Example  │ Name      │ Result                                                    │
├──────────┼───────────┼───────────────────────────────────────────────────────────┤
│$a ==  $b │ Equal     │ TRUE if $a is equal to $b after type juggling.            │
│$a === $b │ Identical │ TRUE if $a is equal to $b, and they are of the same type. │
└──────────┴───────────┴───────────────────────────────────────────────────────────┘

بشكل فضفاض == مقارنة متساوية

إذا كنت تستخدم == عامل التشغيل، أو أي عامل مقارنة آخر يستخدم مقارنة فضفاضة مثل !=, <> أو ==, ، عليك دائمًا أن تنظر إلى سياق لمعرفة ماذا وأين ولماذا يتم تحويل شيء ما لفهم ما يجري.

تحويل القواعد

نوع جدول المقارنة

كمرجع ومثال يمكنك رؤية جدول المقارنة في يدوي:

مقارنات فضفاضة مع ==

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ TRUE  │ FALSE │   1   │   0   │  -1   │  "1"  │  "0"  │ "-1"  │ NULL  │ array() │ "php" │  ""   │
├─────────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼─────────┼───────┼───────┤
│ TRUE    │ TRUE  │ FALSE │ TRUE  │ FALSE │ TRUE  │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE   │ TRUE  │ FALSE │
│ FALSE   │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ TRUE  │ TRUE    │ FALSE │ TRUE  │
│ 1       │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ 0       │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE   │ TRUE  │ TRUE  │
│ -1      │ TRUE  │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "1"     │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "0"     │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "-1"    │ TRUE  │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE   │ FALSE │ FALSE │
│ NULL    │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ TRUE    │ FALSE │ TRUE  │
│ array() │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ TRUE    │ FALSE │ FALSE │
│ "php"   │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ TRUE  │ FALSE │
│ ""      │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE   │ FALSE │ TRUE  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

حازم === مقارنة متطابقة

إذا كنت تستخدم === عامل التشغيل، أو أي عامل مقارنة آخر يستخدم مقارنة صارمة مثل !== أو ===, ، فيمكنك دائمًا التأكد من أن الأنواع لن تفعل ذلك بطريقة سحرية التغيير، لأنه لن يكون هناك تحويل مستمر.لذلك، مع المقارنة الصارمة، يجب أن يكون النوع والقيمة متماثلين، وليس القيمة فقط.

نوع جدول المقارنة

كمرجع ومثال يمكنك رؤية جدول المقارنة في يدوي:

مقارنات صارمة مع ===

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ TRUE  │ FALSE │   1   │   0   │  -1   │  "1"  │  "0"  │ "-1"  │ NULL  │ array() │ "php" │  ""   │
├─────────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼─────────┼───────┼───────┤
│ TRUE    │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ FALSE   │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ 1       │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ 0       │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ -1      │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "1"     │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "0"     │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "-1"    │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE   │ FALSE │ FALSE │
│ NULL    │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE   │ FALSE │ FALSE │
│ array() │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE    │ FALSE │ FALSE │
│ "php"   │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ TRUE  │ FALSE │
│ ""      │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ TRUE  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

نصائح أخرى

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

أمثلة:

1 === 1: true
1 == 1: true
1 === "1": false // 1 is an integer, "1" is a string
1 == "1": true // "1" gets casted to an integer, which is 1
"foo" === "foo": true // both operands are strings and have the same value

تحذير:مثيلان من نفس الفئة مع أعضاء مكافئين لا يتطابقان مع === المشغل أو العامل.مثال:

$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)

صورة تساوي ألف كلمة:

PHP مزدوج يساوي == مخطط المساواة:

enter image description here

PHP الثلاثي يساوي === مخطط المساواة:

enter image description here

كود المصدر لإنشاء هذه الصور:

https://github.com/sentientmachine/php_equality_charts

معلم التأمل

أولئك الذين يرغبون في الحفاظ على عقلهم، لا يقرأون المزيد لأن أيًا من هذا لن يكون له أي معنى، باستثناء القول أن هذه هي الطريقة التي تم بها تصميم الجنون الكسيري لـ PHP.

  1. NAN != NAN لكن NAN == true.
  2. == سيتم تحويل المعاملات اليسرى واليمنى إلى أرقام إذا كان اليسار رقمًا.لذا 123 == "123foo", ، لكن "123" != "123foo"
  3. في بعض الأحيان تكون السلسلة السداسية بين علامتي الاقتباس عائمة، وستكون مفاجئة أنها تطفو ضد إرادتك، مما يتسبب في حدوث خطأ في وقت التشغيل.

  4. == ليست متعدية لأن "0"== 0, ، و 0 == "" لكن "0" != ""

  5. متغيرات PHP التي لم يتم الإعلان عنها بعد تعتبر خاطئة، على الرغم من أن PHP لديها طريقة لتمثيل متغيرات غير محددة، إلا أن هذه الميزة معطلة ==.
  6. "6" == " 6", "4.2" == "4.20", ، و "133" == "0133" لكن 133 != 0133.لكن "0x10" == "16" و "1e3" == "1000" سيتم الكشف عن هذا التحويل المفاجئ للسلسلة إلى النظام الثماني دون تعليماتك أو موافقتك، مما يتسبب في حدوث خطأ في وقت التشغيل.

  7. False == 0, "", [] و "0".

  8. عندما تكون الأرقام كبيرة بما فيه الكفاية فهي == اللانهاية.

  9. فئة جديدة هي == إلى 1.

  10. False هي القيمة الأكثر خطورة لأن False == بالنسبة لمعظم المتغيرات الأخرى، وغالبًا ما يتعارض مع غرضها.

يأمل:

إذا كنت تستخدم PHP، فلا تستخدم عامل يساوي مزدوج لأنه إذا كنت تستخدم يساوي ثلاثية، فإن حالات الحافة الوحيدة التي يجب أن تقلق بشأنها هي NAN والأرقام القريبة جدًا من اللانهاية بحيث يتم إرسالها إلى اللانهاية.مع تساوي مزدوج، أي شيء يمكن أن يكون مفاجأة == إلى أي شيء أو، أو يمكن أن يكون مفاجئًا ضد إرادتك و != لشيء من الواضح أنه ينبغي أن يكون على قدم المساواة.

في أي مكان تستخدمه == في PHP، هناك رائحة كريهة للكود بسبب وجود 85 خطأ فيه تم الكشف عنها من خلال قواعد الصب الضمنية التي يبدو أنها مصممة من قبل ملايين المبرمجين الذين يبرمجون بالحركة البراونية.

فيما يتعلق بالجافا سكريبت:

يعمل عامل التشغيل === بنفس عمل عامل التشغيل ==، ولكنه يتطلب ألا يكون لمعاملاته نفس القيمة فحسب، بل أيضًا نفس نوع البيانات.

على سبيل المثال، سيعرض النموذج أدناه "x وy متساويان"، ولكن ليس "x وy متطابقان".

var x = 4;
var y = '4';
if (x == y) {
    alert('x and y are equal');
}
if (x === y) {
    alert('x and y are identical');
}

إضافة إلى الإجابات الأخرى المتعلقة بمقارنة الكائنات:

== يقارن الكائنات باستخدام اسم الكائن وقيمه.إذا كان هناك كائنان من نفس النوع ولهما نفس قيم الأعضاء، $a == $b يعطي صحيحا.

=== يقارن معرف الكائن الداخلي للكائنات.حتى لو كان الأعضاء متساويين $a !== $b إذا لم يكونوا بالضبط نفس الكائن.

class TestClassA {
    public $a;
}

class TestClassB {
    public $a;
}

$a1 = new TestClassA();
$a2 = new TestClassA();
$b = new TestClassB();

$a1->a = 10;
$a2->a = 10;
$b->a = 10;

$a1 == $a1;
$a1 == $a2;  // Same members
$a1 != $b;   // Different classes

$a1 === $a1;
$a1 !== $a2; // Not the same object

بأبسط العبارات:

== يتحقق إذا مقابل (القيمة فقط)

=== يتحقق مما إذا كان نفس (القيمة والنوع)


يعادل مقابل.نفس:تشبيه

1 + 1 = 2 + 0 (مقابل)

1 + 1 = 1 + 1 (نفس)


في PHP:

صحيح == 1 (صحيح - ما يعادل القيمة)

صحيح ===1 (خطأ - ليس هو نفسه في القيمة والنوع)

  • صحيح هو منطقية
  • 1 هو كثافة العمليات

الأمر كله يتعلق بأنواع البيانات.خذ أ BOOL (صحيح أو خطأ) على سبيل المثال:

true يساوي أيضا 1 وfalse يساوي أيضا 0

ال == لا يهتم بأنواع البيانات عند المقارنة:لذا، إذا كان لديك متغير هو 1 (والذي يمكن أن يكون أيضًا true):

$var=1;

ومن ثم قارن مع ==:

if ($var == true)
{
    echo"var is true";
}

لكن $var لا يساوي في الواقع true, ، أليس كذلك؟لها قيمة int 1 بدلا من ذلك، والذي بدوره، يساوي صحيحا.

مع ===, ، يتم فحص أنواع البيانات للتأكد من أن المتغيرين/الكائنات/أي شيء يستخدم نفس النوع.

فإذا فعلت

if ($var === true)
{
    echo "var is true";
}

هذا الشرط لن يكون صحيحا، كما $var !== true انه فقط == true (إذا كنت تعرف ما أعنيه).

لماذا تحتاج إلى هذا؟

بسيطة - دعونا نلقي نظرة على إحدى وظائف PHP: array_search():

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

لذلك إذا فعلت:

$arr = array("name");
if (array_search("name", $arr) == false)
{
    // This would return 0 (the key of the element the val was found
    // in), but because we're using ==, we'll think the function
    // actually returned false...when it didn't.
}

إذن، هل ترى كيف يمكن أن تكون هذه مشكلة الآن؟

معظم الناس لا يستخدمون == false عند التحقق مما إذا كانت الدالة تُرجع خطأ.وبدلاً من ذلك، يستخدمون !.ولكن في الواقع، هذا هو بالضبط نفس الاستخدام ==false, ، فإذا فعلت:

$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)

لذلك بالنسبة لأشياء مثل هذه، يمكنك استخدام === بدلاً من ذلك، بحيث يتم التحقق من نوع البيانات.

أحد الأمثلة على ذلك هو أن سمة قاعدة البيانات يمكن أن تكون فارغة أو "":

$attributeFromArray = "";
if ($attributeFromArray ==  ""){}  //true
if ($attributeFromArray === ""){}  //true
if ($attributeFromArray ==  null){}  //true
if ($attributeFromArray === null){}  //false

$attributeFromArray = null;
if ($attributeFromArray ==  ""){}  //true
if ($attributeFromArray === ""){}  //false
if ($attributeFromArray ==  null){}  //true
if ($attributeFromArray === null){}  //true

منح x = 5

1) المشغل :== هو "يساوي". x == 8 هو زائف
2) المشغل :=== "يساوي تمامًا" (القيمة والنوع) x === 5 صحيح، x === "5" هو زائف

قليل من الأمثلة

var_dump(5 == 5);    // True
var_dump(5 == "5");  // True because == checks only same value not type
var_dump(5 === 5);   // True
var_dump(5 === "5"); // False because value are same but data type are different.

ملاحظة.

== يقارن القيمة فقط، ولن يهتم بأنواع البيانات

ضد.

=== يقارن القيم وأنواع البيانات

$a = 5;   // 5 as an integer

var_dump($a == 5);       // compare value; return true
var_dump($a == '5');     // compare value (ignore type); return true
var_dump($a === 5);      // compare type/value (integer vs. integer); return true
var_dump($a === '5');    // compare type/value (integer vs. string); return false

كن حذرا رغم ذلك.وهنا مشكلة سيئة السمعة.

// 'test' is found at position 0, which is interpreted as the boolean 'false'
if (strpos('testing', 'test')) {
    // code...
}

ضد.

// true, as strict comparison was made (0 !== false)
if (strpos('testing', 'test') !== false) {
    // code...
}

باختصار، تعمل === بنفس الطريقة التي تعمل بها == في معظم لغات البرمجة الأخرى.

تتيح لك لغة PHP إجراء مقارنات لا معنى لها حقًا.مثال:

$y = "wauv";
$x = false;
if ($x == $y)
    ...

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

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

إذا نظرت إلى دليل PHP، سترى أن الكثير من الوظائف تُرجع "خطأ" إذا فشلت الوظيفة، لكنها قد تُرجع 0 في سيناريو ناجح، ولهذا السبب يوصون بإجراء "if (function() !== كاذبة)" لتجنب الأخطاء.

يمكنك استخدام === لاختبار ما إذا كانت الدالة أو المتغير خطأ أم لا، بدلاً من مجرد معادلة خطأ (صفر أو سلسلة فارغة).

$needle = 'a';
$haystack = 'abc';
$pos = strpos($haystack, $needle);
if ($pos === false) {
    echo $needle . ' was not found in ' . $haystack;
} else {
    echo $needle . ' was found in ' . $haystack . ' at location ' . $pos;
}

في هذه الحالة، سترجع strpos 0 وهو ما يعادل خطأ في الاختبار

if ($pos == false)

أو

if (!$pos)

وهذا ليس ما تريده هنا.

أما بالنسبة لمتى يتم استخدام أحدهما على الآخر، خذ على سبيل المثال fwrite() وظيفة في PHP.

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

if (!fwrite(stuff))
{
    log('error!');
}

يمكن أن يُرجع صفرًا (ويُعتبر ناجحًا)، ولا يزال يتم تفعيل حالتك.الطريقة الصحيحة ستكون:

if (fwrite(stuff) === FALSE)
{
    log('error!');
}

PHP هي لغة مكتوبة بشكل فضفاض.يسمح استخدام عامل المساواة المزدوج بإجراء فحص فضفاض للمتغير.

إن التحقق من القيمة بشكل فضفاض سيسمح لبعض القيم المتشابهة، ولكن غير المتساوية، بأن تتساوى مع نفسها:

  • ''
  • باطل
  • خطأ شنيع
  • 0

كل هذه القيم سوف تتساوى باستخدام عامل المساواة المزدوج.

php == هو عامل مقارنة يقارن قيمة المتغيرات.لكن === يقارن القيمة ونوع البيانات.

على سبيل المثال،

<?php 
  $var1 = 10;
  $var2 = '10';

  if($var1 == $var2) {
    echo 'Variables are equal';
  } else {
    echo 'Variables are not equal';
  }
?>

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

ولكن إذا استخدمنا === بدلاً من ==، فسيكون الناتج "المتغيرات غير متساوية".يقوم PHP أولاً بمقارنة قيمة المتغير ثم نوع البيانات.هنا القيم هي نفسها، ولكن أنواع البيانات مختلفة.

المتغيرات لها نوع وقيمة.

  • $var = "test" عبارة عن سلسلة تحتوي على "test"
  • $var2 = 24 هو عدد صحيح، وقيمة v هي 24.

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

if ($var == 1) {... do something ...}

يجب على PHP تحويل ("لإرسال") $var إلى عدد صحيح.في هذه الحالة، يكون "$var == 1" صحيحًا لأن أي سلسلة غير فارغة يتم إرسالها إلى 1.

عند استخدام ===، عليك التحقق من أن القيمة وTHE TYPE متساويان، لذا فإن "$var === 1" غير صحيح.

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

if(myFunction() == false) { ... error on myFunction ... }

هذا الرمز خاطئ كما لو myFunction() بإرجاع 0، يتم تحويله إلى خطأ ويبدو أن لديك خطأ.الكود الصحيح هو :

if(myFunction() === false) { ... error on myFunction ... }

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

ال === ومن المفترض أن المشغل للمقارنة بالضبط المساواة في المحتوى بينما == سيقارن المشغل المساواة الدلالية.على وجه الخصوص، سيتم إجبار السلاسل على الأرقام.

المساواة موضوع واسع.يرى مقالة ويكيبيديا عن المساواة.

<?php

    /**
     * Comparison of two PHP objects                         ==     ===
     * Checks for
     * 1. References                                         yes    yes
     * 2. Instances with matching attributes and its values  yes    no
     * 3. Instances with different attributes                yes    no
     **/

    // There is no need to worry about comparing visibility of property or
    // method, because it will be the same whenever an object instance is
    // created, however visibility of an object can be modified during run
    // time using ReflectionClass()
    // http://php.net/manual/en/reflectionproperty.setaccessible.php
    //
    class Foo
    {
        public $foobar = 1;

        public function createNewProperty($name, $value)
        {
            $this->{$name} = $value;
        }
    }

    class Bar
    {
    }
    // 1. Object handles or references
    // Is an object a reference to itself or a clone or totally a different object?
    //
    //   ==  true   Name of two objects are same, for example, Foo() and Foo()
    //   ==  false  Name of two objects are different, for example, Foo() and Bar()
    //   === true   ID of two objects are same, for example, 1 and 1
    //   === false  ID of two objects are different, for example, 1 and 2

    echo "1. Object handles or references (both == and    ===) <br />";

    $bar = new Foo();    // New object Foo() created
    $bar2 = new Foo();   // New object Foo() created
    $baz = clone $bar;   // Object Foo() cloned
    $qux = $bar;         // Object Foo() referenced
    $norf = new Bar();   // New object Bar() created
    echo "bar";
    var_dump($bar);
    echo "baz";
    var_dump($baz);
    echo "qux";
    var_dump($qux);
    echo "bar2";
    var_dump($bar2);
    echo "norf";
    var_dump($norf);

    // Clone: == true and === false
    echo '$bar == $bar2';
    var_dump($bar == $bar2); // true

    echo '$bar === $bar2';
    var_dump($bar === $bar2); // false

    echo '$bar == $baz';
    var_dump($bar == $baz); // true

    echo '$bar === $baz';
    var_dump($bar === $baz); // false

    // Object reference: == true and === true
    echo '$bar == $qux';
    var_dump($bar == $qux); // true

    echo '$bar === $qux';
    var_dump($bar === $qux); // true

    // Two different objects: == false and === false
    echo '$bar == $norf';
    var_dump($bar == $norf); // false

    echo '$bar === $norf';
    var_dump($bar === $norf); // false

    // 2. Instances with matching attributes and its values (only ==).
    //    What happens when objects (even in cloned object) have same
    //    attributes but varying values?

    // $foobar value is different
    echo "2. Instances with matching attributes  and its values (only ==) <br />";

    $baz->foobar = 2;
    echo '$foobar' . " value is different <br />";
    echo '$bar->foobar = ' . $bar->foobar . "<br />";
    echo '$baz->foobar = ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // false

    // $foobar's value is the same again
    $baz->foobar = 1;
    echo '$foobar' . " value is the same again <br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$baz->foobar is ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // true

    // Changing values of properties in $qux object will change the property
    // value of $bar and evaluates true always, because $qux = &$bar.
    $qux->foobar = 2;
    echo '$foobar value of both $qux and $bar is 2, because $qux = &$bar' . "<br />";
    echo '$qux->foobar is ' . $qux->foobar . "<br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$bar == $qux';
    var_dump($bar == $qux); // true

    // 3. Instances with different attributes (only ==)
    //    What happens when objects have different attributes even though
    //    one of the attributes has same value?
    echo "3. Instances with different attributes (only ==) <br />";

    // Dynamically create a property with the name in $name and value
    // in $value for baz object
    $name = 'newproperty';
    $value = null;
    $baz->createNewProperty($name, $value);
    echo '$baz->newproperty is ' . $baz->{$name};
    var_dump($baz);

    $baz->foobar = 2;
    echo '$foobar' . " value is same again <br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$baz->foobar is ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // false
    var_dump($bar);
    var_dump($baz);
?>

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

$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n ==  $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );

يعطي:

 equal
 not equal

لاحظ أن هذه ليست حالة "خطأ تقريبي".الرقمان متساويان تمامًا حتى آخر بت، لكن لهما أنواع مختلفة.

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

في العالم الحقيقي، من المحتمل أن يكون هذا مشكلة في البرامج التي تتعامل مع التواريخ بعد عام 2038، على سبيل المثال.في هذا الوقت، ستتطلب الطوابع الزمنية لنظام UNIX (عدد الثواني منذ 00:00:00 بالتوقيت العالمي المنسق) أكثر من 32 بت، لذلك سيتحول تمثيلها "بطريقة سحرية" إلى المضاعفة في بعض الأنظمة.لذلك، إذا قمت بحساب الفرق بين وقتين، فقد ينتهي بك الأمر ببضع ثوانٍ، ولكن كنتيجة مضاعفة، بدلاً من النتيجة الصحيحة التي تحدث في عام 2017.

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

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

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

هناك نوعان من الاختلافات بين == و === في صفائف PHP والكائنات التي أعتقد أنها لم تذكر هنا؛صفيفان بأنواع مفاتيح وكائنات مختلفة.

صفيفان بأنواع مختلفة من المفاتيح

إذا كان لديك مصفوفة بفرز مفاتيح ومصفوفة أخرى بفرز مفاتيح مختلف، فإنهما مختلفان تمامًا (على سبيل المثال:استخدام ===).قد يتسبب ذلك في قيامك بفرز مصفوفة باستخدام المفاتيح، ومحاولة مقارنة المصفوفة التي تم فرزها بالمصفوفة الأصلية.

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

// Define an array
$arr = [];

// Adding unsorted keys
$arr["I"] = "we";
$arr["you"] = "you";
$arr["he"] = "they";

الآن، لدينا مصفوفة مفاتيح غير مرتبة (على سبيل المثال، يأتي "هو" بعد "أنت").خذ بعين الاعتبار نفس المصفوفة، ولكننا قمنا بفرز مفاتيحها أبجديًا:

// Declare array
$alphabetArr = [];

// Adding alphabetical-sorted keys
$alphabetArr["I"] = "we";
$alphabetArr["he"] = "they";
$alphabetArr["you"] = "you";

نصيحة:يمكنك فرز مجموعة حسب المفتاح باستخدام كسورت () وظيفة.

الآن لديك مصفوفة أخرى بنوع مفاتيح مختلف عن المصفوفة الأولى.لذلك، سنقوم بمقارنتها:

$arr == $alphabetArr; // true
$arr === $alphabetArr; // false

ملحوظة:قد يكون الأمر واضحا، ولكن المقارنة بين الاثنين مختلف المصفوفات التي تستخدم المقارنة الصارمة تنتج دائمًا false.ومع ذلك، قد يكون هناك صفيفان عشوائيان متساويان في الاستخدام === أم لا.

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

أشياء

تذكر، جسمان مختلفان لا يكونان متساويين تمامًا.هذه الأمثلة من شأنها أن تساعد:

$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;

// Comparing
$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false

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

ملحوظة:اعتبارًا من PHP7، فئات مجهولة تمت أضافتة.ومن النتائج لا يوجد فرق بين new class {} و new stdClass() في الاختبارات أعلاه.

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