مرحبا يا هبر! أوجه انتباهكم إلى ترجمة تقرير ألكسندر كوزمينكو من مؤتمر هونج كونج المفتوح المصدر لعام 2019 (14-15 يونيو).

قبل الانضمام إلى Haxe Foundation كمطور لمترجم Haxe ، كان ألكساندر مهنيًا في برمجة PHP لمدة 10 سنوات ، حتى يعرف موضوع التقرير.

مقدمة صغيرة حول ماهية Haxe هي مجموعة من الأدوات الأساسية لإنشاء البرامج ، والتي تشمل:
- مترجم يقوم ، بناءً على النظام الأساسي الهدف ، إما بترجمة رمز Haxe المصدر إلى شفرة المصدر بلغات البرمجة الأخرى (C ++ ، PHP ، Java ، C # ، JavaScript ، Python ، Lua) ، أو يتم التحويل البرمجي مباشرة إلى رمز بايت للجهاز الظاهري (JVM ، neko ، HashLink ، فلاش)
- مكتبة قياسية تنفذ لجميع المنصات المدعومة
- يوفر Haxe أيضًا أدوات للتفاعل مع الشفرة المكتوبة بلغة النظام الأساسي الهدف.
- مدير المكتبة القياسي - haxelib

ظهر دعم PHP في Haxe منذ فترة طويلة - في عام 2008. في إصدارات Haxe حتى 3.4.7 ضمناً ، تم دعم PHP 5.4 والإصدارات الأحدث ، وبدءًا من الإصدار الرابع ، يدعم Haxe الإصدار 7.0 من PHP والإصدارات الأحدث.

قد تسأل: لماذا يجب على مطور PHP استخدام Haxe؟
السبب الرئيسي لذلك هو القدرة على استخدام نفس المنطق على كل من الخادم والعميل.
فكر في هذا المثال: لديك خادم مكتوب بلغة PHP باستخدام إطار Laravel ، وعدة عملاء كتبوا في JavaScript ، Java ، C #. في هذه الحالة ، لمعالجة تفاعل الشبكة بين الخادم والعميل (منطقه هو نفسه في الأساس) ، ستحتاج إلى كتابة 4 تطبيقات لكل لغة من اللغات المستخدمة. ولكن مع Haxe ، يمكنك كتابة رمز بروتوكول الشبكة مرة واحدة ثم تجميعه / ترجمته تحت منصات مختلفة ، مما يوفر الكثير من الوقت في هذا.

إليك مثال آخر - تطبيق لعبة - صراع Clash of Clans. شارك ألكساندر في تطوير مثل هذه اللعبة: تمت كتابة خادمه بلغة PHP ، العميل المحمول في C # (Xamarin) ، وعميل المتصفح في JavaScript باستخدام إطار Phaser. على العميل والخادم ، تمت معالجة منطق واحد - ما يسمى "المعركة" ، والتي تحسب سلوك وحدات اللاعب على الموقع. في البداية ، تم كتابة رمز القتال لكل من المنصات بشكل منفصل. ولكن بمرور الوقت (وتطور المشروع منذ حوالي 5 سنوات) ، تراكمت الاختلافات في سلوكه على الخادم والعملاء. كان هذا بسبب حقيقة أنه كتب من قبل أشخاص مختلفين ، أدرك كل منهم ذلك بطريقته الخاصة. لهذا السبب ، لم تكن هناك طريقة موثوقة للكشف عن الغشاشين ، لأن المنطق على الخادم تصرف بشكل مختلف تمامًا عن سلوك العميل ، ونتيجة لذلك ، عانى اللاعبون الشرفاء أيضًا. يمكن للخادم حسابهم كغشاشين ولا يحسب نتائج معركة صادقة.
في النهاية ، تقرر نقل المعركة إلى Haxe ، والتي سمحت بحل المشكلة مع الغشاشين بالكامل ، لأن الآن منطق المعركة تصرفت على جميع المنصات. بالإضافة إلى ذلك ، سمح هذا القرار بتخفيض تكاليف مواصلة تطوير نظام القتال ، كما الآن كان يكفي لمبرمج واحد على دراية Haxe ، بدلا من ثلاثة ، كل منها سيكون مسؤولا عن نظامها الأساسي.

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

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

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

اختلاف آخر في بناء الجملة هو الاختلافات في وصف بنية التحكم switch
. في PHP ، يعمل switch
كما في C. في Haxe ، يعمل بشكل مختلف:
- أولاً ، لا يستخدم المفتاح الكلمة الأساسية
break
- ثانيا ، يمكنك الجمع بين عدة شروط باستخدام
|
(بدلاً من تكرار الكلمة الأساسية case
) - ثالثًا ، يستخدم Haxe مطابقة النمط للمفتاح. لذا ، على سبيل المثال ، يمكنك تطبيق
switch
على المصفوفة ، وفي الظروف يمكنك تحديد الإجراءات وفقًا لمحتويات المصفوفة (تعني العلامة _
أن هذه القيمة لا تزعجنا ويمكن أن تكون أي شيء). سيتم استيفاء الشرط [1, _, 3]
إذا كان الصفيف يتكون من ثلاثة عناصر ، في حين أن العنصر الأول هو 1 ، والثالث هو 3 ، وقيمة العنصر الثاني هي أي.

في Haxe ، كل شيء تعبير ، وهذا يسمح لك بكتابة المزيد من التعليمات البرمجية المدمجة. يمكنك إرجاع قيمة من try
/ catch
، if
أو switch
دون استخدام الكلمة الأساسية المرتجعة داخل هذه البنيات. في المثال أعلاه مع try
/ catch
"يعرف" المترجم أنك تريد إرجاع بعض القيمة ويمكن أن تمر من هذا البناء.

PHP يتحرك تدريجيا نحو كتابة أقوى ، ولكن Haxe لديه بالفعل كتابة ثابتة قوية!
في المثال أعلاه ، نقوم بتعيين المتغير s
القيمة التي تم الحصول عليها من functionReturnsString()
، والتي تُرجع السلسلة. وبالتالي ، فإن نوع المتغير s
عبارة عن سلسلة. وإذا حاولت تمريرها إلى giveMeInteger()
، والتي giveMeInteger()
عددًا صحيحًا كوسيطة ، فسيقوم برنامج التحويل البرمجي Haxe بإلقاء خطأ حول عدم تطابق النوع.
يوضح هذا المثال أيضًا ميزة هامة أخرى من Haxe - type inference - قدرة المترجم على تحديد أنواع المتغيرات بشكل مستقل وفقًا للقيمة التي تم تخصيصها لها.

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

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

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

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

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

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

في PHP ، تكون السلاسل آمنة ثنائية ، لذلك في PHP ، إذا لم تكن بحاجة إلى دعم Unicode ، فإن طرق العمل مع السلاسل تعمل بسرعة كبيرة.
في Haxe ، بدءًا من الإصدار الرابع ، تدعم السلاسل Unicode ، لذلك عند تجميعها في PHP ، سيتم استخدام أساليب من الوحدة النمطية للعمل مع سلاسل mbstring متعددة البايتات ، مما يعني الوصول البطيء إلى الأحرف التعسفية في السلسلة ، وبطء حساب طول السلسلة.
لذلك ، إذا لم تكن بحاجة إلى دعم Unicode ، فيمكنك استخدام أساليب فئة php.NativeString
للعمل مع السلاسل ، والتي سوف تستخدم سلاسل "أصلية" من PHP.

تعرض الشريحة الموجودة على اليسار رمز PHP الذي يستخدم كلاً من الطريقتين اللتين تدعمان Unicode وليسهما.
على اليمين هو رمز Haxe المكافئ. كما ترون ، إذا كنت بحاجة إلى دعم Unicode ، فيجب عليك استخدام أساليب فئة String
، إن لم تكن كذلك ، ثم أساليب فئة php.NativeString
.

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

فيما يلي رمز تعيين الصفيف باستخدام وظيفة السهم. كما ترون ، يقوم برنامج التحويل البرمجي Haxe بتحسين كود PHP الذي تم استلامه في المخرجات بشكل نشط: لا توجد وظيفة مجهولة في الكود الناتج ، بدلاً من ذلك يتم تطبيق الكود في حلقة على كل عنصر من عناصر المصفوفة. بالإضافة إلى map()
ينطبق هذا التحسين أيضًا على طريقة filter()
.
أيضًا ، إذا لزم الأمر ، يمكنك استخدام فئة php.NativeArray
وأساليب PHP المقابلة للعمل مع المصفوفات في Haxe.

يتم تطبيق كائنات مجهولة باستخدام فئة HxAnon
، التي ترث من فئة StdClass
من PHP.

في PHP ، تعد StdClass
فئة إلى مثيلات يتم فيها تحويل كل شيء نحاول تحويله إلى كائن. وسيكون مثالياً لتنفيذ كائنات مجهولة ، إن لم يكن لميزة واحدة من مواصفاتها: في Haxe ، يجب أن يكون الوصول إلى حقل غير موجود لكائن مجهول null
، وفي PHP هذا يطرح تحذيرًا. ولهذا السبب ، كان علي أن أرث من الفئة القياسية من PHP وأضف طريقة سحرية إليها ، والتي عند الوصول إلى خصائص غير موجودة ، فإنها تُرجع.

Haxe يمكن أن تتفاعل مع رمز مكتوب في PHP. للقيام بذلك ، هناك الميزات التالية (على غرار إمكانيات التفاعل مع رمز JavaScript):
- الط (الخارجيين)
- تضمين رمز php مباشرة في رمز haxe
- فصول خاصة من حزمة
php.*
php.Syntax
- php.Syntax
PHP الخاصة التي ليست في Haxephp.Global
- php.Global
PHP العالمية الأصليةphp.Const
- php.Const
PHP العالمية الأصليةphp.SuperGlobal
- لمتغيرات PHP php.SuperGlobal
يمكن الوصول إليها من كل مكان ( $_POST
، $_GET
، $_SERVER
، إلخ)

لأن يستخدم PHP نموذج OOP الكلاسيكي ، ثم كتابة externs لأنه عملية بسيطة إلى حد ما. في الواقع ، تعتبر العناصر الخارجية لفصول PHP عبارة عن "ترجمة" حرفية تقريبًا في Haxe ، باستثناء بعض الكلمات الرئيسية.
كمثال ، سيبدو الرمز الخارجي لفئة PHP من الشريحة أعلاه كما يلي:

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

لإدراج كود PHP ، يتم php.Syntax
وحدة php.Syntax
خاصة. التعليمات البرمجية المضافة بهذه الطريقة لا تخضع لأي تحويل أو تحسين بواسطة برنامج التحويل البرمجي Haxe.
بالإضافة إلى php.Syntax
، لا يزال لدى php.Syntax
القدرة على استخدام php.Syntax
.

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