وسيطات الدالة كثوابت بت في PHP

مرحبا يا هبر! أقدم لكم ترجمة مقال بقلم ليام هاميت : حجج Bitmask الثابتة في PHP .

تحتوي PHP على العديد من الوظائف القياسية التي تقبل الحجج المنطقية في شكل ثوابت مضمنة بأرقام ثنائية.
يتم دمج هذه القيم في وسيطة واحدة للدالة من أجل نقل العديد من الأعلام المنطقية بطريقة مضغوطة.


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




كيف يتم استخدامه في وظائف PHP


تحتوي PHP 7.2 ، بما في ذلك الإضافات ، على أكثر من 1800+ ثوابت محددة مسبقًا ، ويتم استخدام بعضها كحجج للدوال.
أحد الأمثلة على مثل هذا التطبيق هو خيار جديد في PHP 7.3 ، والذي يسمح لك برمي استثناء من وظيفة json_encode لأخطاء التحويل.


 json_encode($value, JSON_THROW_ON_ERROR); 

باستخدام | (أو) عامل تشغيل أحادي المعامل ، تعمل العديد من وسائط الدالة كواحدة. مثال من وثائق PHP:


 json_encode($value, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE); 

لا شيء على الإطلاق.


لكن مع ذلك ، كيف يعمل؟


إن تطبيق عمليات bitwise لتحقيق نفس التأثير في عالم الوظائف المعرفة من قبل المستخدم هو أمر بسيط بالفعل ، ولكنه يتطلب على الأقل معرفة أساسية عن البتات وكيف تعمل عمليات bitwise في PHP.


يمكن تحديد الأعداد الصحيحة في نظام الأرقام العشري (الأساس 10) أو الست عشري (الأساس 16) أو الثماني (الأساس 8) أو نظام الأرقام الثنائية (الأساس 2). [...]
للكتابة بترميز ثنائي ، يجب أن تضع الرقم 0b قبل الرقم.
- php.net

أمثلة على الثوابت بمجموعة مختلفة من الأرقام الثنائية:


 const A = 0b0001; // 1 const B = 0b0010; // 2 const C = 0b0100; // 4 const D = 0b1000; // 8 

انتبه إلى مثال وتسلسل الأرقام. تمثل كل قيمة ثنائية قيمة مضاعفة لكل صفر في النهاية. الأصفار بين 0b و 1 اختيارية ، ولكنها يمكن أن تساعد في محاذاة التعليمات البرمجية المصدر.


لحسن الحظ ، نحن بحاجة إلى فهم كيفية عمل عمليتين بتات فقط.


أحادي المعامل OR


لا تخلط بين عامل التشغيل | ( أحادي المعامل "OR" ) مع عامل التشغيل الأكثر استخدامًا || ( منطقي "OR" ) ، والذي يتم العثور عليه عادةً في if else .
البت "OR" هو عملية ثنائية يكون عملها مكافئًا لتطبيق "OR" منطقي على كل زوج من البتات الموجودة في نفس المواضع في التمثيلات الثنائية للمعاملات. بمعنى آخر ، إذا كانت كلتا البتتين المطابقتين للمعاملات 0 ، فإن البت الثنائي للنتيجة هو 0 ؛ إذا كان بت واحد على الأقل من الزوج 1 ، فإن البت الثنائي للنتيجة هو 1.


مثال على عملية أحادي المعامل "OR":


 const A = 0b0001; const B = 0b0010; const C = 0b0100; const D = 0b1000; A | B === 0b0011; A | C | D === 0b1101; 

أحادي المعامل AND (AND)


وبالمثل ، يجب عدم الخلط بين عامل التشغيل & ( أحادي المعامل AND ) وعامل التشغيل && يُستخدم بشكل متكرر ( منطقي AND ).
A bitwise AND هي عملية ثنائية يكافئ عملها تطبيق AND المنطقي لكل زوج من البتات الموجودة في نفس المواضع في التمثيلات الثنائية للمعاملات. وبعبارة أخرى ، إذا كانت البتتان المقابلتان للمعاملات 1 ، فإن البت الثنائي الناتج هو 1 ؛ إذا كان بت واحد على الأقل من الزوج 0 ، فإن البت الثنائي الناتج هو 0.


 const A = 0b0001; const B = 0b0010; const C = 0b0100; const D = 0b1000; const VALUE = 0b1010; A & B === 0b0000; //      A  B A & C & D === 0b0000; //      A, B  C A & A === 0b0001; //      A  A & VALUE === 0b0000; //      A  VALUE B & VALUE === 0b0010; //  1    B,    VALUE 

هل يمكن أن يكون لرقم منطقي؟


ومن الجدير بالذكر أنه في PHP يوجد مفهوم " التلاعب بالنوع" ( نوع التلاعب ). بلغة غير الخبراء ، هذا يعني أن (PHP) سيحاول تلقائيًا تحويل البيانات من نوع إلى آخر ، إذا لزم الأمر.
إذا فهمت كيف تحدث مثل هذه التحولات ، فيمكن أن يكون هذا أداة مفيدة.
على سبيل المثال ، نحن نعلم أن الرقم 0 يعمل false عند التحويل إلى قيمة منطقية ، بينما ستكون جميع الأرقام الأخرى true . تذكر أن هذه القيم الثنائية التي نعمل معها هي في الواقع أعداد صحيحة؟


لتلخيص!


الآن يمكننا دمج هذه المعرفة لإنشاء if بناء ، الرمز الذي سيتم تنفيذه فقط إذا كانت نتيجة عملية bitwise بين الأرقام ليست 0b0000 (أو 0 ، والتي يتم تحويلها إلى false ).


 const A = 0b0001; const B = 0b0010; function f($arg = 0) { if ($arg & A) { echo 'A'; } if ($arg & B) { echo 'B'; } } f(); // nothing f(A); // 'A' f(B); // 'B' f(A | B); // 'AB' 

تعمل وظائف PHP المضمنة الأخرى (مثل json_encode ) بنفس الطريقة.


هل يستحق ذلك؟


ربما لديك الآن رغبة في تطبيق هذا النهج للوظائف مع عدد كبير من الحجج التي تشارك في الإنشاءات الشرطية ، ولكن هناك عدد من العيوب في معالجة إشارات الدالة أحادي البت:


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

ومع ذلك ، الآن أنت تعرف كيف تفعل ذلك.




قراءة قائمة طويلة من تعريفات الثوابت يمكن أن تكون مطولة وصعبة ، لذلك هنا وظيفة مساعدة تبسط تعريفها.

Source: https://habr.com/ru/post/ar423257/


All Articles