أهم العوامل (operators) الموجودة في PHP – PHP

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

عامل تجميع Null (‏Null coalescing) (??)

عُرِّف هذا العامل الجديد في الإصدار PHP 7، يُرجع هذا العامل معامَله (operand) الأول إذا كان ذو قيمة ليست null وإلا فإنّه يرجع معامَله الثاني. إليك المثال التالي:

$name = $_POST['name'] ?? 'nobody';

وهذه الشيفرة مكافئة لكل من:

if (isset($_POST['name'])) {
    $name = $_POST['name'];
} else {
    $name = 'nobody';
}

والشيفرة:

$name = isset($_POST['name']) ? $_POST['name'] : 'nobody';

يمكن أيضًا أن تسلسل هذا العامل (مع دلالات ارتباط صحيحة):

$name = $_GET['name'] ?? $_POST['name'] ?? 'nobody';

وهذه الشيفرة مكافئة للشيفرة التالية:

if (isset($_GET['name'])) {
    $name = $_GET['name'];
} elseif (isset($_POST['name'])) {
    $name = $_POST['name'];
} else {
    $name = 'nobody';
}

ملاحظة: عند استخدام عامل التجميع لضمّ السلاسل النصية يجب استخدام الأقواس ().

$firstName = "John";
$lastName = "Doe";
echo $firstName ?? "Unknown" . " " . $lastName ?? "";

خرج الشيفرة السابقة هو John، لو كانت قيمة المتغير ‎$firstName‎ هي null وقيمة المتغير ‎$lastName هي Doe عندها سيكون الخرج Unknown Doe، ليكون لدينا الخرج John Doe يجب استخدام الأقواس كما يلي:

$firstName = "John";
$lastName = "Doe";
echo ($firstName ?? "Unknown") . " " . ($lastName ?? "");

عامل السفينة الفضائية (<=>)

عرّفت PHP نوعًا جديدًا من العوامل وهو عامل السفينة الفضائية (Spaceship) يمكن استخدامه للموازنة بين التعابير، يُرجع هذا العامل 1-، 0 أو 1 إذا كان التعبير الأول أقل من، يساوي أو أكبر من التعبير الثاني.

// الأعداد الصحيحة
print (1 <=> 1); // 0
print (1 <=> 2); // -1
print (2 <=> 1); // 1

// الأعداد العشرية
print (1.5 <=> 1.5); // 0
print (1.5 <=> 2.5); // -1
print (2.5 <=> 1.5); // 1

// السلاسل النصية
print ("a" <=> "a"); // 0
print ("a" <=> "b"); // -1
print ("b" <=> "a"); // 1

لا يمكن الموازنة بين الكائنات وسيؤدي ذلك إلى سلوك غير معرّف.

يعدّ هذا العامل مفيدًا بشكلٍ خاص عند تعريف المستخدم لدالة موازنة باستخدام usort أو uasort أو uksort. يمكن لدالة مجهولة استخدام <=> إذا كان الهدف منها ترتيب مصفوفة من الكائنات وفقًا لخاصيّة الوزن بالنظر إلى مصفوفة كائنات يجب ترتيبها وفقًا لخاصية الوزن، يمكن لدالة مجهولة مثلًا استخدام <=> لتُرجع القيمة المتوقعة من دوال الترتيب.

usort($list, function($a, $b) { 
    return $a->weight <=> $b->weight; 
});

يتطلب هذا تعبير أكثر تفصيلًا في PHP 5.

usort($list, function($a, $b) {
    return $a->weight < $b->weight ? -1 : ($a->weight == $b->weight ? 0 : 1);
});

عامل التنفيذ (“)

يتألف عامل التنفيذ في PHP من علامتي اقتباس مائلتين (“) ويستخدم لتنفيذ أوامر الصدفة، ويرجع خرج الأمر وبالتالي يمكن تخزينه في متغير.

// أمر الحصول على قائمة بأسماء الملفات
$output = `ls`;
echo "<pre>$output</pre>";

لاحظ أنّ معامل التنفيذ والدالة shell_exec()‎ يعطيان نفس النتيجة.

عوامل الزيادة (++) والنقصان (–)

يمكن زيادة المتغيرات أو نقصانها بمقدار 1 باستخدام ++، — على التوالي، ويمكن أن يأتي كل منهما قبل المتغير أو بعده ولكل حالة دلالتها كما سنوضح في الأمثلة التالية:

$i = 1;
echo $i; // 1

// $i بمقدار 1 ثم يرجع $i عامل الزيادة السابقة يزيد المتغير
echo ++$i; // 2

// $i بمقدار 1 ثم يرجع $i عامل النقصان السابق ينقص المتغير
echo --$i; // 1

//ثم يزيده بمقدار 1 $i عامل الزيادة اللاحقة يرجع المتغير
echo $i++; // 1 (2 الآن هي $i لكن قيمة المتغير)

//ثم ينقصه بمقدار 1 $i عامل النقصان اللاحق يرجع المتغير
echo $i--; // 2 (1 الآن هي $i لكن قيمة المتغير)

يمكنك الاطلاع على المزيد حول عوامل الزيادة والنقصان من هنا.

العامل الثلاثي (?:)

يمكن أن تعدّ العامل الثلاثي تعليمة if سطرية، يتألف من 3 أجزاء: العامل وخرجين وله الصياغة العامة التالية:

$value = <operator> ? <true value> : <false value>

إذا قُيِّم العامل على أنّه true ستُرجَع القيمة الموجودة في الكتلة الأولى (<true value>) وإلا ستُرجَع القيمة الموجودة في الكتلة الثانية (<false value>)، وبما أنّه أسندنا نتيجة العامل الثلاثي للمتغير ‎$value فستُخزّن القيمة المُرجعة فيه.

مثال:

$action = empty($_POST['action']) ? 'default' : $_POST['action'];

سيحتوي المتغير ‎$action السلسلة ‘default’ إذا كانت نتيجة التعبير empty($_POST['action'])‎ هي true وإلا سيحتوي على قيمة ‎$_POST['action']‎.

يُقيَّم التعبير (expr1) ? (expr2) : (expr3) إلى expr2 إذا قُيِّم expr1 على أنّه true وإلى expr3 إذا قُيِّم expr1 على أنّه false.

من الممكن أن تحذف الجزء الأوسط من العامل الثلاثي، يرجع التعبير expr1 ?: expr3 قيمة expr1 إذا كانت نتيجته هي true وإلا تُرجع قيمة expr3. يُشار عادةً للعامل ‎?:‎‎ على أنّه عامل إلفيس (Elvis operator).

يتصرف هذا العامل مثل عامل تجميع null ?? باستثناء أنّ الأخير يتطلّب أن يكون المعامَل اليساري null بينما العامل ‎?:‎‎ يحاول أن يحلل المعامَل اليساري إلى قيمة منطقية والتحقق فيما إذا كانت قيمته false أو لا.

مثال:

function setWidth(int $width = 0){
    $_SESSION["width"] = $width ?: getDefaultWidth();
}

في هذا المثال تقبل الدالة setWidth المعامل width أو ستكون قيمته الافتراضية 0 لتغيير قيمة width في الجلسة. إذا كانت قيمة ‎$width هي 0 (أي لم تُعطى قيمة للمتغير ‎$width) فستكون قيمته المنطقية false وستُستخدم قيمة getDefaultWidth()‎ بدلًا منه، بينما لو كانت قيمة المتغير ‎$width المنطقية هي true لن نحتاج لاستدعاء الدالة getDefaultWidth()‎.

العوامل المنطقية (&&/AND و ||/OR)

يوجد في PHP صيغتان مختلفتان للعوامل المنطقية AND وOR.

المعامل إذا كان true تكون النتيجة
$a and $b قيمة كل من $a و $b هي true
$a && $b قيمة كل من $a و $b هي true
$a or $b قيمة كل من $a أو $b هي true
$a || $b قيمة كل من $a أو $b هي true

لاحظ أن العوامل && و|| لها أولوية أعلى من and وor. لاحظ الجدول التالي:

التقييم نتيجة $e طريقة التقييم
$e = false || true True $e = (false || true)‎
$e = false or true False ‎($e = false) or true

لذا من الأفضل استخدام && و|| بدلًا من and وor.

عوامل السلاسل النصية (String Operators)

هناك عاملان للسلاسل النصية:

  • عامل الربط (concatenation) (.):
$a = "a";
$b = "b";
$c = $a . $b; // $c => "ab"
  • عامل الربط الإسنادي (=.):
$a = "a";
$a .= "b"; // $a => "ab"

عوامل الكائن والصنف

يمكن الوصول لعناصر الكائنات أو الأصناف باستخدام عامل الكائن ‎(->)‎ وعامل الصنف (::).

class MyClass {
    public $a = 1;
    public static $b = 2;
    const C = 3;
    public function d() { return 4; }
    public static function e() { return 5; }
}

$object = new MyClass();
var_dump($object->a); // int(1)
var_dump($object::$b); // int(2)
var_dump($object::C); // int(3)
var_dump(MyClass::$b); // int(2)
var_dump(MyClass::C); // int(3)
var_dump($object->d()); // int(4)
var_dump($object::d()); // int(4)
var_dump(MyClass::e()); // int(5)

$classname = "MyClass";
var_dump($classname::e()); // int(5)

لاحظ أنّه ليس ضروريًا كتابة $ بعد عامل الكائن (‎$object->a بدلًا من ‎$object->$a‎)، وذلك لا ينطبق على عامل الصف أي أنّه من الضروري كتابة $. أما بالنسبة للثابت المعرّف في الصف لا نستخدم $ أبدًا.

من الممكن أن نكتب التعليمة var_dump(MyClass::d());‎ إذا كانت الدالة function d()‎ لا تشير إلى الكائن:

class MyClass {
    private $a = 1;
    public function d() {
        return $this->a;
    }
}

$object = new MyClass();
var_dump(MyClass::d()); // Error!

يسبب هذا ظهور الخطأ:

PHP Fatal error: Uncaught Error: Using $this when not in object context

لهذه العوامل ارتباط يساري يمكن استخدامه للتسلسل:

class MyClass {
    private $a = 1;

    public function add(int $a) {
        $this->a += $a;
    return $this;
    }

    public function get() {
        return $this->a;
    }
}

$object = new MyClass();
var_dump($object->add(4)->get()); // int(5)

ولها أيضًا الأولوية الأعلى، حتى أعلى من النسخ (clone):

class MyClass {
    private $a = 0;
    public function add(int $a) {
        $this->a += $a;
        return $this;
    }

    public function get() {
        return $this->a;
    }
}

$o1 = new MyClass();
$o2 = clone $o1->add(2);
var_dump($o1->get()); // int(2)
var_dump($o2->get()); // int(2)

تُضاف قيمة ‎$o1 قبل أن يُنسَخ الكائن.

لاحظ أنّ استخدام الأقواس للتأثير على الأولوية لا يعمل في PHP الإصدار 5 والأقدم منه (لكنه يؤثر في PHP 7):

// من الشيفرة السابقة MyClass استخدام الصف
$o1 = new MyClass();
$o2 = (clone $o1)->add(2); 
// PHP 7 لكنه يعمل بشكل صحيح في PHP 5 السطر السابق يؤدي إلى خطأ في

var_dump($o1->get()); // int(0) in PHP 7
var_dump($o2->get()); // int(2) in PHP 7

عوامل الإسناد المجمّعة (=+ وغيرها)

عوامل الإسناد المجمّعة هي اختصار لعملية على متغيرٍ ما ثم إسناد قيمة جديدة لهذا المتغير.

العمليات الحسابية

// إسناد بسيط
$a = 1;

// (1 + 2) => 3 أي النتيجة '$a = $a + 2'; يُقرأ السطر التالي كأنّه
$a += 2;

// (3 - 1) => 2 في السطر التالي $a قيمة
$a -= 1;

// (2 * 2) => 4 في السطر التالي $a قيمة
$a *= 2;

// (16 / 2) => 8 في السطر التالي $a قيمة
$a /= 2;

// (باقي القسمة‎) (8 % 5) => 3 في السطر التالي $a قيمة 
$a %= 5;

// المعامل + في المصفوفات
$arrOne = array(1);
$arrTwo = array(2);
$arrOne += $arrTwo;
var_dump($arrOne);
// array(1) { [0]=> int(1) }

ملاحظة: عند استخدام العامل + في المصفوفات فإنّه يُرجع المصفوفة في الطرف اليميني مضافة إلى نهاية المصفوفة في الطرف اليساري، في حال كانت المفتاح نفسه موجودًا في المصفوفتين فإنّه يستخدم القيمة الموجودة في المصفوفة اليسارية ويتجاهل قيمة هذا المفتاح في المصفوفة اليمينية.

معالجة عدة مصفوفات معًا

$a **= 2;
// (2مرفوعة للقوة ‏‎ 4) (4 ** 2) => 16 هي $a تصبح قيمة 

الربط والإسناد المجمّع لسلسلة نصية:

$a = "a";
$a .= "b"; // $a => "ab"

عوامل الإسناد المجمّعة لعمليات الأعداد الثنائية:

$a = 0b00101010;
// 42 الآن هي $a قيمة

$a &= 0b00001111;
// (and عملية الأعداد الثنائية) ‎(00101010 & 00001111) => 00001010 الآن هي $a قيمة

$a |= 0b00100010;
// (or عملية الأعداد الثنائية) ‎(00001010 | 00100010) => 00101010 الآن هي $a قيمة

$a ^= 0b10000010;
// (xor عملية الأعداد الثنائية) ‎(00101010 ^ 10000010) => 10101000 الآن هي $a قيمة

$a >>= 3;
// (3 انزياح يميني بمقدار) ‎(10101000 >> 3) => 00010101 الآن هي $a قيمة

$a <<= 1;
// (1 انزياح يساري بمقدار) ‎(00010101 << 1) => 00101010 الآن هي $a قيمة

تغيير أولوية عامل (مع الأقواس)

يُحدّد عامل الأولوية (operator precedence) الترتيب الذي تُقيَّم فيه العوامل، ففي المثال التالي:

$a = 2 * 3 + 4;

يأخد المتغير ‎$a القيمة 10، في البداية يُقيّم 2‎ * 3 (الضرب له أولوية أعلى من الجمع) ومحصلة النتيجة الفرعية 6 مضافًا إليها 4 تساوي 10.

يمكن أن تتغير الأولوية باستخدام الأقواس:

$a = 2 * (3 + 4);

في الشيفرة السابقة قيمة المتغير ‎$a تصبح 14 لأنّ ‎(3 + 4)‎ يُقيّم أولًا.

الإسناد البسيط (=)

$a = "some string";

للمتغير ‎$a الآن القيمة some string.

نتيجة تعبير الإسناد هي أنّ القيمة تُصبح مُسنَدة، لاحظ أننا استخدمنا الإشارة = للإسناد وليس للمساواة.

$a = 3;
$b = ($a = 5);

تقوم الشيفرة السابقة بالتالي:

  • يُسند السطر 1 القيمة 3 للمتغير ‎$a.
  • يُسند السطر 2 القيمة 5 للمتغير ‎$a. ينتج عن هذا التعبير القيمة 5 أيضًا.
  • ثم يُسند السطر 2 نتيجة التعبير بين القوسين (5) للمتغير ‎$b. لذا لدينا الآن قيمة كل من ‎$a و‎$b هي 5.

الارتباط (Association)

الارتباط اليساري

إذا تساوت أولوية عاملين فإنّ الترابط يحدد التجميع:

$a = 5 * 3 % 2;
// (5 * 3) % 2 => (15 % 2) => 1 الآن هي $a قيمة

إنّ * و% لهما الأولوية نفسها وترابط يساري، يُجمَّع الضرب لأنه يحدث أولًا (يسارًا).

$a = 5 % 3 * 2;
// (5 % 3) * 2 => (2 * 2) => 4 الآن هي $a قيمة

لاحظ أنّ عامل باقي القسمة يحدث أولًا (يسارًا) ولذا يُجمّع.

الارتباط اليميني

$a = 1;
$b = 1;
$a = $b += 1;

لكل من المتغيرين ‎$a و‎$b القيمة 2 لأنّ ‎$b += 1 جُمّعت ثم أُسندت النتيجة (‎$b = 2) للمتغير ‎$a.

عوامل الموازنة

المساواة

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

لدينا في المثال التالي المتغيرين ‎$a و‎$b متساويين ولكنهما غير متطابقين.

$a = 4;
$b = '4';

if ($a == $b) {
    // هذه العبارة ستُطبع
    echo 'a and b are equal';
}

if ($a === $b) {
    // هذه العبارة لن تُطبع
    echo 'a and b are identical';
}

تُحوَّل السلاسل النصية العددية إلى أعداد صحيحة عند استخدام عامل المساواة.

موازنة الكائنات

يوازن === بين كائنين بالتأكد من إذا كان الطرفان نفس النسخة تمامًا من صنف ما، هذا يعني أنّ نتيجة new stdClass() === ‎new stdClass()‎ هي false حتى لو أنشئوا بنفس الطريقة وكان لهما نفس القيم.

يوازن === بين كائنين بشكلٍ متكرر متحققًا من كونهم متساويين (تساويًا عميقًا) (deep equals)، وهذا يعني أنّه ‎$a == ‎$b إذا كان ‎$a و‎$b:

  • من نفس الصنف.
  • لهم نفس مجموعة الخاصيّات بما في ذلك الخاصيّات الديناميكية.
  • من أجل كل ‎$property فإنّ نتيجة كل ‎$a->property == ‎$b->property‎‎‎ هي true (لذا التحقق يتكرر).

العوامل الأخرى الشائعة الاستعمال

تتضمن:

  • أكبر من ‎(>)‎.
  • أصغر من ‎(<)‎.
  • أكبر من أو يساوي ‎(>=)‎.
  • أصغر من أو يساوي ‎(<=)‎.
  • لا يساوي ‎(!=)‎.
  • لا يطابق ‎‎(!==)‎.

أكبر من:

‎$a > $b‎: تُرجع true إذا كانت قيمة ‎$a أكبر من قيمة ‎$b، وإلا ترجع false.

مثال:

var_dump(5 > 2);
// bool(true)

var_dump(2 > 7);
// bool(false)

أصغر من:

‎$a < $b: تُرجع true إذا كانت قيمة ‎$a أصغر من قيمة ‎$b، وإلا ترجع false.

مثال:

var_dump(5 < 2);
// bool(false)

var_dump(1 < 10);
// bool(true)

أكبر من أو يساوي:

‎$a >= $b: تُرجع true إذا كانت قيمة ‎$a أكبر من قيمة ‎$b أو تساويها، وإلا ترجع false.

مثال:

var_dump(2 >= 2);
// bool(true)

var_dump(6 >= 1);
// bool(true)

var_dump(1 >= 7);
// bool(false)

أصغر من أو يساوي:

‎$a <= $b: تُرجع true إذا كانت قيمة ‎$a أصغر من قيمة ‎$b أو تساويها، وإلا ترجع false.

مثال:

var_dump(5 <= 5);
// bool(true)

var_dump(5 <= 8);
// bool(true)

var_dump(9 <= 1);
// bool(false)

لا يساوي/يطابق:

نعيد صياغة المثال السابق حول المساواة لكن في هذا المثال سيكون لدينا ‎$a و‎$b غير متطابقين:

$a = 4;
$b = '4';

if ($a != $b) {
    // هذه العبارة لن تُطبع
    echo 'a and b are not equal';
}

if ($a !== $b) {
    // هذه العبارة ستُطبع
    echo 'a and b are not identical'; 
}

عوامل الأعداد الثنائية (Bitwise Operators)

عوامل الأعداد الثنائية البادئة‎

تشبه العوامل الثنائية العوامل المنطقية لكنها تُنفَّذ لكل بت بدلًا من كل قيمة منطقية.

// يعكس قيمة البتات NOT ~ العامل
printf("%'06b", ~0b110110); // 001001

عوامل قناع بتّي-قناع بتّي (Bitmask-bitmask)

العامل الثنائي AND‎ & يُعيد 1 مكان كل بت له القيمة 1 في كِلا المعامَلين.

printf("%'06b", 0b110101 & 0b011001); // 010001

العامل الثنائي OR | يُعيد 1 مكان كل بت له القيمة 1 في أحد المعامَلين أو كلاهما.

printf("%'06b", 0b110101 | 0b011001); // 111101

العامل الثنائي XOR ^ يُعيد 1 مكان كل بت له القيمة 1 في أحد المعامَلين فقط.

printf("%'06b", 0b110101 ^ 0b011001); // 101100

أمثلة لاستخدام الأقنعة البتّية

يمكن استخدام هذه العوامل للتعامل مع الأقنعة البتّية، مثال على ذلك:

file_put_contents("file.log", LOCK_EX | FILE_APPEND);

اُستخدم هنا العامل | لدمج اثنين من الأقنعة البتّية، بالرغم من أنّ العامل + له نفس التأثير أيضًا إلا أنّ | تؤكد أنّك تدمج الأقنعة البتّية ولست فقط تجمع رقمين صحيحين عاديين.

class Foo{
    const OPTION_A = 1;
    const OPTION_B = 2;
    const OPTION_C = 4;
    const OPTION_A = 8;
    private $options = self::OPTION_A | self::OPTION_C;

    public function toggleOption(int $option){
        $this->options ^= $option;
    }

    public function enable(int $option){
        // بغض النظر عن حالته الأصلية $option تمكين
        $this->options |= $option;
    }

    public function disable(int $option){
        // بغض النظر عن حالته الأصلية دون التأثير على البتات الأخرى $option تمكين
        $this->options &= ~$option;
    }

    // تُرجع الدالة التالية فيما إذا كانت إحدى الخيارت ممكّنة
    public function isOneEnabled(int $options) : bool{
        return $this->options & $option !== 0;
        // بت مرتفع فقد نعالج عدد صحيح سالب $options استخدمنا ==! بدلًا من > لأنّه إذا كانت قيمة
    }

    // تُرجع الدالة التالية فيما إذا كانت كل الخيارت ممكّنة
    public function areAllEnabled(int $options) : bool{
        return ($this->options & $options) === $options;
        // لاحظ استخدام الأقواس للحذر من أولوية العامل
    }
}

يستخدم هذا المثال (بفرض ‎$option يحوي بت واحد دومًا):

  • العامل ^ لتبديل الأقنعة البتّية بشكلٍ ملائم.
  • العامل | لضبط بت بغض النظر عن حالته الأصلية أو باقي البتات.
  • العامل ~ لتحويل العدد الصحيح الذي فيه بت واحد مضبوط (قيمته 1) إلى عدد صحيح فيه بت واحد غير مضبوط (قيمته 0).
  • العامل & لإلغاء ضبط بت باستخدام خصائص & التالية:

    • بما أنّ ‎&=‎ مع بت مضبوط لن تفعل شيء ‎((1 & 1) === 1, (0 & 1) === 0)‎ فإنّ استخدام ‎&=‎ مع عدد صحيح له بت واحد غير مضبوط لن يضبط هذا البت بدون التأثير على البتات الأخرى.
    • استخدام ‎&=‎ مع بت غير مضبوط لن يضبط ذلك البت ‎((1 & 0) === 0, (0 & 0) === 0)‎.
  • استخدام العامل & مع قناع بتّي آخر سيصفّي كل البتات الباقية غير المضبوطة في القناع البتّي هذا.

    • إذا كان في الخرج أي بت مضبوط فهذا يعني أن الخياران ممكّنان.
    • إذا كان في الخرج كل بتات القناع البتّي مضبوطة، هذا يعني أنّ كل خيارات القناع البتّي ممكّنة.

تذكر دومًا أنّ عوامل الموازنة هذه ‎(< > <= >= == === != !== <> <=>)‎ لها أولوية أعلى من عوامل قناع بتّي-قناع بتّي (& ^ |)، وبما أنّ نتائج العمليات الثنائية تُوازن عادةً باستخدام عوامل الموازنة هذه فيجب الانتباه إلى هذه النقطة.

عوامل إزاحة البت (Bit-shifting)

عامل الإزاحة إلى اليسار ‎<<‎ يزيح كل البتات إلى اليسار (الأكثر أهمية) وفق عددٍ معطى، ويتجاهل كل البتات المزاحة. يكافئ هذا العامل عدم ضبط بتات ‎$x العليا والضرب بالقوة رقم ‎$x للعدد 2.?

printf("%'08b", 0b00001011<< 2); // 00101100

assert(PHP_INT_SIZE === 4); // نظام 32 بت
printf("%x, %x", 0x5FFFFFFF << 2, 0x1FFFFFFF << 4); // 7FFFFFFC, FFFFFFFF

عامل الإزاحة إلى اليمين ‎>>‎ يزيح البتات إلى اليمين (الأقل أهمية) ويتجاهل البتات المزاحة، يكافئ هذا العامل القسمة على القوة رقم ‎$x للعدد 2 ويتجاهل الجزء غير الصحيح.

printf("%x", 0xFFFFFFFF >> 3); // 1FFFFFFF

أمثلة لاستخدام عوامل إزاحة البت

القسمة السريعة على 16 (أداء أفضل من ‎‎/= 16)

$x >>= 4;

يتجاهل هذا العامل في أنظمة 32 بت كل البتات في العدد الصحيح ويضبط قيمتها إلى 0، وفي أنظمة 64 بت يؤدي إلى عدم ضبط البتات 32 الأكثر أهمية ويحافظ على الأقل أهمية.

$x = $x << 32 >> 32;

32 بت الأكثر أهمية تكافئ ‎$x & 0xFFFFFFFF. لاحظ أنّه في هذا المثال استخدام printf("%'06b")‎ يُرجع القيمة بشكل 6 أرقام ثنائية.

عوامل الأنواع instanceof (‏type operator)

يمكننا استخدام العامل instanceof الثنائي بدءًا من PHP الإصدار 5 للتحقق فيما إذا كانت الكائنات من نفس الصنف.

المعامل الأول (اليساري) هو الكائن الذي نريد التحقق منه، إذا لم يكن هذا المتغير كائن فإنّ العامل instanceof سيرجع false، إذا اُستخدم تعبير ثابت سيُرمى خطأ.

المعامل الثاني (اليميني) هو الصنف الذي نريد الموازنة معه، يمكن أن نعبر عن الصنف باسم الصنف نفسه أو بمتغير من نوع سلسلة نصية يعبر عن اسم الصنف (وليس سلسلة نصية ثابتة) أو بكائن من ذلك الصنف.

class MyClass {
}

$o1 = new MyClass();
$o2 = new MyClass();
$name = 'MyClass';

// true القيمة $a في الحالات التالية يأخذ المتغير
$a = $o1 instanceof MyClass;
$a = $o1 instanceof $name;
$a = $o1 instanceof $o2;

$b = 'b';
$a = $o1 instanceof 'MyClass'; // parse error: constant not allowed
$a = false instanceof MyClass; // fatal error: constant not allowed
$a = $b instanceof MyClass; 
// false (ليس كائن $b المتغير)

يمكن أيضًا أن نستخدم العامل instanceof للتحقق فيما إذا كان كائن ما نسخة من صنف يوسّع صنف آخر أو يحقق واجهة ما:

interface MyInterface {
}

class MySuperClass implements MyInterface {
}

class MySubClass extends MySuperClass {
}

$o = new MySubClass();

// true القيمة $a في الحالات التالية يأخذ المتغير
$a = $o instanceof MySubClass;
$a = $o instanceof MySuperClass;
$a = $o instanceof MyInterface;

يمكننا استخدام العامل not ! للتحقق فيما إذا كان الكائن ليس من صنف ما:

class MyClass {
}

class OtherClass {
}

$o = new MyClass();
$a = !$o instanceof OtherClass; // true

لاحظ أننا لا نحتاج الأقواس حول ‎$o instanceof MyClass لأنّ العامل instanceof له أولوية أعلى من ! بالرغم من أنّ إضافة الأقواس تجعل الشيفرة أكثر قابلية للقراءة.

تحذيرات

إذا لم يكن الصنف موجودًا تُستدعى دوال التحميل التلقائي المسجلّة لمحاولة إيجاد الصنف، في الإصدارات السابقة للإصدار PHP 5.1.0 فإنّ العامل instanceof قد يقوم بهذه الاستدعاءات وبالتالي يحدد الصنف فعليًا (وإذا لم يحدَّد الصنف سيحدث خطأ فادح (fatal error)).

// 5.1.0 الإصدارات السابقة للإصدار
class MyClass {
}

$o = new MyClass();
$a = $o instanceof OtherClass; 
// غير معرّف OtherClass الصنف
/* معرّف في المحمّل التلقائي المسجل فإنّه سيُحمّل OtherClass إذا كان الصنف
وإذا لم يكن هذا الصنف معرّفًا (OtherClass ليس من $a المتغير)  false القيمة $a ويأخذ المتغير 
سيُرمى خطأً فادحًا */

$name = 'YetAnotherClass';
$a = $o instanceof $name;
// غير معرّف YetAnotherClass الصنف
//غير معرّف YetAnotherClass ويبقى الصنف false القيمة المنطقية $a يأخذ المتغير

بدءًا من الإصدار 5.1.0 فإنّ المحمّلات التلقائية المسجلّة لن تُستدعى في مثل هذه الحالات.

الإصدارات الأقدم من PHP (قبل الإصدار 5.0)

يمكن استخدام الدالة is_a في الإصدارات السابقة للإصدار 5.0 لتحديد فيما إذا كان الكائن من صنف معين، أُهملت هذه الدالة في PHP 5 ولم تُهمل في PHP 5.3.3.

ترجمة -وبتصرف- للفصل [Operators] من كتاب PHP Notes for Professionals


Source link

اظهر المزيد
زر الذهاب إلى الأعلى

أنت تستخدم إضافة Adblock

الاعلانات هي مصدرنا الوحيد لدفع التكلفة التشغيلية لهذا المشروع الريادي يرجى الغاء تفعيل حاجب الأعلانات