هنالك العديد من المصادر القديمة على شبكة الإنترنت لتعلم لغة PHP التي تؤثر سلباً على المطورين الجدد، بحيث تقدم لهم عدة مفاهيم وأسس قد انتهى عصرها وصارت قديمة، بالإضافة لشيفرات برمجية غير آمنة. PHP: بالطريقة الصحيحة هو دليل سريع وسهل للطرق القياسية لبرمجة وتطوير PHP الأكثر شهرة، وروابط لدروس ودلائل موثوقة على شبكة الإنترنت وكل ما يعتبره المساهمون كمعايير قياسية حتى هذه اللحظة.
لا يوجد قاعدة موحدة للبرمجة باستخدام PHP. هذا الموقع يهدف إلى تعريف مطوري PHP الجدد إلى بعض المواضيع التي قد لا يعرفها أو يتطرق لها إلا بعد فوات الأوان، ويهدف أيضاً لتوضيح وتنقيح إيجابيات المواضيع التي قد تم التطرق إليها واستخدامها منذ عدة سنين من دون إعادة النظر إليها. لن يدلك هذا الموقع لاستخدام أدوات أو أساليب محددة، ولكن يوفر لك مقتراحات لأكثر من خيار، مع توضيح الفرق ما بينها إن أمكن ذلك مع أمثلة وطرق استخدام.
هذا الموقع حي ومحدث وسوف يتم تحديثه باستمرار بمعلومات وأمثلة مفيدة جديدة حين توافرها.
PHP: بالطريقة الصحيحة متوفر بعدة لغات اخرى:
يمكن الحصول على أحدث نسخة من PHP بالطريقة الصحيحة في صيغة PDF ، EPUB ، MOBI. من Leanpub
قم بالمساعدة لجعل هذا الموقع أفضل مصدر لمبرمجي PHP الجدد قم بالمساهمة في تطوير المحتوى العربي على GitHub أو المحتوى الأصلي باللغة الإنجليزية على GitHub.
ملاحظة: يتم التحديث وإضافة المحتوى وفقاً للمحتوى باللغة الإنجليزية، إذا كان هنالك أي إضافة تود إدراجها فضلاً قم بزيارة المحتوى المحتوى الأصلي باللغة الإنجليزية على GitHub.
PHP: بالطريقة الصحيحة لديه عدة بانرات صور يمكنك أن تضعها في موقعك. قم بالدعم ودع المطورين الجدد يعرفون المصدر لمعرفة معلومات مفيدة!
إذا كنت تريد البدء بالتطوير بلغة PHP، إذاً قم باستخدام آخر نسخة مستقرة من PHP 7.1. PHP 7.1 هي نسخة جديدة، تم إضافة العديد من المميزات المميزات الجديدة مقارنة بالنسخ القديمة 5.×. قد تم إعادة بناء محرك اللغة من جديد، فالآن PHP أصبحت أسرع من سبيقاتها.
في الغالب حتى الآن سوف تجد أن PHP 5.× ما تزال مستخدمة مع العلم أن آخر نسخة من PHP 5.× هي PHP 5.6. وهذه النسخة لا تعتبر خياراً سيئًـا ولكن يتوجب عليك التحديث إلى آخر نسخة مستقرة في أقرب فرصة. سيتوقف الدعم وضخ التحديثات الأمنية على النسخة PHP 5.6 بعد العام 2018. عملية التحديث هي عملية سهلة للغاية، ربما قد تواجه بضع ماشكل توافقية مع الأعمال المكتوبة بالإصدارات السابقة ولكن يمكنك الاطلاع على صفحة التوافقية مع الإصدارات السابقة. إذا كنت غير متأكد من وجود دالة أو ميزة في أي إصدار، يمكنك التأكد عبر زيارة موقع دليل توثيق PHP php.net.
منذ إصدار PHP 5.4 بإمكانك تعلم PHP بدون تنصيب أي إضافات أو تخصيصات، مع التمتع بكل خصائص خادم الويب المعتاد. لتشغيل الخادم قم بتنفيذ هذا الأمر من نافذة الأوامر من مجلد مشروعك الرئيس:
يحتوي نظام التشغيل OS X على إصدار PHP ولكنها عادة ما تكون غير حديثة. فالنسخة OS X Mavericks تحتوي على الإصدار 5.4.17، والنسخة OS X Yosemite تحتوي على الإصدار 5.5.9، والنسخة OS X El Capitan تحتوي على الإصدار 5.5.29 وSierra 5.6.24. لكن مع انطلاق إصدار PHP 7.1 لم تعد هذه الإصدارات جيدة للاستخدام.
هنالك عدة طرق لتنصيب PHP على نظام تشغيل Mac OS X.
Homebrew هو عبارة عن مدير تطبيقات لنظام تشغيل Mac OS x، يساعدك على تنصيب PHP وملحقاتها بكل سهولة. Homebrew PHP هو المستودع الذي يحتوي كل ما يتعلق بـ PHP لمدير التطبيقات Homebrew، ويمكنك من تنصيب PHP بكل سهولة.
حتى هذه اللحظة يمكنك تنصيب كل من php53
، php54
، php55
، php56
،php71
، php70
باستخدام الأمر brew install
، ويمكنك التحويل
فيما بينهم بتعديل متغير PATH
. أو يمكنك استخدام brew-php-switcher للتحويل التلقائي.
مشروع MacPorts هو مشروع مفتوح المصدر يهدف لتصميم نظام سهل الاستخدام لتجميع وتنصيب وتحديث البرامج المفتوحة المصدر لكل من برامج سطور الأوامر X11، Aqua على نظام تشغيل Mac OS X.
يدعم MacPorts الملفات بلغة الآلة المبنية مسبقاً (Pre-Compiled Binaries) لكيلا تقوم بإعادة بناء كل حزمة من متطلبات النظام من الملفات المصدرية (tarball files)، فهي توفر لك سهولة تنصيب الحزم خصوصاً عندما لا يحتوي نظامك على إحداها.
حتى هذه اللحظة يمكنك تنصيب كل من php54
، php55
، php56
، php70
، php71
باستخدام الأمر port install
مثلاً:
sudo port install php56
sudo port install php71
ويمكنك تشغيل الأمر select
لتَّحويل بين الإصدارات المتوفرة.
sudo port select --set php php71
phpbrew هي إداة لتنصيب وإدارة أكثر من إصدار PHP. فهي أداة مفيدة جداً عندما يتطلب مشروعان إصدارات مختلفة من PHP وتريد تشغيلهما بدون الحاجة لنظام تشغيل افتراضي.
وسيلة أخرى متاحة وهي php-osx.liip.ch فهي توفر وسيلة تنصيب لنسخة واحدة لكل من الإصدارات ابتداء من 5.3 حتى 7.1. تتميز بأنها لا تستبدل ملفات حزمة PHP binaries المدمجة مع نظام Apple، ولكنها تعمل على التنصيب في مكان آخر (/usr/local/php5).
وسيلة أخرى تمكنك من التحكم بإصدارات PHP وتنصيبها، وذلك عن طريق بنائها بنفسك. في هذه الحالة تَأَكَّد من تنصيب Xcode، أو“Command Line Tools for XCode” التابعة لـ Apple ويمكن تحميلها “Command Line Tools for XCode” من قسم Mac للمطورين (Mac Developer Center).
كل الحلول السابق ذكرها تتلخص بأنك تطبق عملية تنصيب PHP بنفسك، وهي لا تشمل تنصيب برامج مثل Apache, Nginx أو حتى خادم SQL. «الكل في واحد» هي حلول متكاملة مثل MAMP و XAMPP فهي تقوم بتنصيب كل تلك البرامج وضبطهم معاً، ولكن رغم سهولة التنصيب فإن مثل هذه الحلول تفتقر للمرونة.
يمكنك تحميل الملفات التنفيذية من windows.php.net/download. بعد تنصيب PHP يفضل إضافة وضبط مسار التنصيب (المسار الذي يحتوي على ملف php.exe داخله) إلى المتغير العام PATH حتى تتمكن من تشغيل PHP من أي مكان في النظام.
لأغراض التعلم والتطوير المحلي يمكنك استخدام الخادم المُدْمج مع PHP 5.4 أو أعلى، حتى لا تحتاج عملية الضبط مع برامج أخرى للخادم. إذا كنت تفضل «الكل في واحد» وهي برامج تحتوي على كل الحزم التي قد تحتاجها من خادم ويب وخادم قاعدة بيانات بالإضافة لـ PHP، إذاً فبرامج مثل Web Platform Installer، XAMPP، EasyPHP، OpenServer ، WAMP ستساعدك عند تنصيب بيئة تطوير متكاملة بسرعة على نظام تشغيل Windows. الجدير بالذكر أنَّ هذه الأدوات تختلف قليلاً مما هي عليه على خوادم مرحلة التنفيذ النهائية، فيجب عليك توخي الحيطة والحذر ومراعاة الإختلافات ما بين البيئتين. مثلا تقوم بالتطوير على بيئة عمل Windows ويتم التنفيذ في بيئة نهائية Linux.
إذا كنت تريد تشغيل بيئتك النهائية على نظام تشغيل Windows حينها IIS7 سوف يُوَفِّر لك أداءً عالٍ ومستقرا. يمكنك استخدام phpmanager (إضافة واجهة عمل رسومية لـ IIS7) لإدارة وضبط PHP بكل سهولة. IIS7 يكون معه FastCGI مدمج وجاهز للاستخدام، كل ما عليك هو ضبط PHP كمعالج (Handler). للدعم ومصادر أخرى هناك صفحة مخصصة على iis.net خصيصاً لـPHP.
بشكل عام تشغيل برامجك على بيئات متعددة في مرحلة التطوير والتنفيذ قد يؤدي لظهور أخطاء ومشاكل مختلفة وغريبة.. لذلك عندما تقوم بتنصيب بيئة تطوير على Windows ثم تقوم بتنصيبها على بيئة عمل نهائية Linux (أو أي نظام تشغيل آخر) يجب أخذ استخدام بيئة تشغيل افتراضية بعين الاعتبار.
كريس تانكرسلي لديه مقالة ممتازة على مدونته الشخصية للأدوات التي يستخدمها عندما يقوم بتطوير البرامج على بيئة Windows.
مجتمع لغة PHP هو مجتمع ضخم ومتنوع، يتألف من عدد لا يعد ولا يحصى من المكتبات، وأطر عمل، و مكونات وعناصر أخرى. من الشائع أن يختار المطورون عدة خيارات منها ودمجها في مشروع واحد. من المهم أن يتم تقييد الشفرة البرمجية للغة PHP (قدر الإمكان) بأسلوب برمجي معين لكي يَسْهُل على المطورين التعامل المشترك وفهم محتوى الشفرة البرمجية في مكتبات مشاريعهم.
قامت Framework Interop Group بتقديم وإجازة سلسلة من الأساليب المُوصَى بها. ليس كل هذه التوصيات هي توصيات تتعلق بأسلوب كتابة الشفرة البرمجية، ولكن تحديداً ما يتعلق منها بأسلوب الكتابة هم: PSR-0، PSR-1، PSR-2، PSR-4. هذه التوصيات هي عبارة عن مجموعة من القواعد التي تستعملها مشاريع وتطبيقات كبرى مثل Drupal، Zend، Symfony، Laravel، CakePHP، phpBB، AWS SDK، FuelPHP، Lithium.. وغيرها. يمكنك استخدام هذه الأساليب والتوصيات في مشروعك الخاص أو الإستمرار في استخدام أسلوبك الخاص في الكتابة.
من الأمثل أن تقوم بكتابة شفرة برمجية تتماشى مع مجموعة قواعد قياسية متعارف عليها. ويتم تطبيق هذه القواعد عن طريق دمج الأساليب سابقة الذِّكر PSR أو أساليب أخرى تم اعتمادها من قبل PEAR أو Zend. هذا يعني أنه يمكن لأي مطور آخر أن يقرأ ويفهم عملك نظراً لأن محتواه يخضع لطريقة كتابة معتمدة وتستخدمها كثير من التطبيقات والتطبيقات الفرعية الأخرى التي قد تستخدمها مع مشروعك.
يمكنك استخدام أدوات فحص الشفرة البرمجية ومعرفة ما إذا كانت تخضع لأي من التوصيات مثل PHP_CodeSniffer، وهنالك إضافات يمكن تنصيبها على محرر النصوص مثل Sublime Text وتتميز بأنها تتفاعل معك في أثناء الكتابة مباشرة.
يمكنك إصلاح الشفرة البرمجية وإخضاعها لأحد الأساليب القياسية باستخدام أي من هذه الأدوات:
ويمكنك أيضاً تشغيل phpcs
يدوياً من سطر الأوامر:
phpcs -sw --standard=PSR2 file.php
بعد التنفيذ سوف تظهر أخطاء ووصفٌ لكيفية إصلاحها. أيضاً يمكن الإستفادة من هذا الأمر عبر إضافته كـ git hook بحيث تتحقق من أن جميع الشفرة البرمجية تتبع الأسلوب القياسي وإصلاح الأخطاء حتى يكون بالإمكان إعتمادها في المستودع (Repository).
إذا كنت تمتلك PHP_CodeSniffer عندها يمكنك تصحيح أسلوب الشفرة البرمجية تلقائياً باستخدام PHP Code Beautifier and Fixer.
phpcbf -w --standard=PSR2 file.php
أو عن طريق خيار آخر وهو استخدام PHP Coding Standards Fixer. باستخدام هذا الأخير سيقوم بإظهار نوع الأخطاء قبل إصلاحها.
php-cs-fixer fix -v --level=psr2 file.php
اللغة الإنجليزية هي المفضلة لكل التسميات والرموز والعلامات وجميع بنية الشفرة البرمجية. يمكن كتابة الملاحظات بأي لغة يمكن قراءتها من قبل المطورين الحاليين أو المحتملين.
PHP هي لغة مرنة ومتغيرة حيث أنها تدعم عدة أساليب برمجية. فقد تطورت بشكل ملحوظ خلال السنين الماضية وأضافت البرمجة كائنية التوجه (Object Oriented) في إصدار PHP 5.0 (سنة 2004) وأضافت الدَّوال المجهولة (anonymous functions) ونطاق التسميات (namespaces) في الإصدار PHP 5.3 (سنة 2009) وأضافت السِّمَات (traits) في إصدار PHP 5.4 (سنة 2012).
تحتوي PHP على خَوَاصِ البرمجة الكائنية بشكل كامل وذلك يشمل الأصناف (class) والأصناف المجردة (abstract class) والمنافذ (interface) والوراثة (inheritance) والبنائيات (constructor) والاستنساخ (clone) والاستثناء (exception) والمزيد …
تدعم PHP دوال «المستوى الأول»، بمعنى أنه يمكن إسناد دالة إلى متغير. كل من «دوال المستخدم» والدوال المدمجة مع اللغة يمكن إحالتها باستخدام متغيرات ومناداتها بصورة حيوية. يمكن تمرير الدوال كقيم إلى دوال أخرى (خاصية تسمى الدوال العليا higher-order Functions) والدوال نفسها بإمكانها إرجاع دوال أخرى!
الإستدعاء (recursion) الذاتي، وهي خاصية تتيح للدَّالة أن تنادي نفسها، وهي مدعومة من قبل اللغة ولكن معظم الشفرة بلغة PHP تعتمد على التكرار.
الدوال المجهولة (anonymous functions) خاصية موجودة منذ الإصدار PHP 5.3 (سنة 2009، مع دعم «الإغلاق» closures).
أضافت PHP 5.4 إمكانية إسناد دوال مجهولة وكائنات مغلقة لنطاق الكائن وقد تم التطوير للإستدعاءات حتى يمكن استخدامها مع كل الدوال في أي حال.
call_user_func_array()
تدعم PHP أيضاً عدة أشكال من البرمجة التحويلية (Meta programming) عبر عدة وسائل مثل واجهة برمجة تطبيقات الإنعكاس (reflection API)
والدوال السحرية (Magic Methods). هناك عدة دوال سحرية مثل __get()
، __set()
، __clone()
، __toString()
، __invoke()
وغيرها والتي تتيح للمُطَوِّر ربطها بتصرفات الكائنات. يقول مطورو لغة Ruby أن لغة PHP تفتقر إلى الدالة method_missing
، ولكنها موجودة
وتتمثل في كل من __call()
و __callStatic()
.
قد سبق ذِكْرُ أنَّ مجتمع PHP يحتوي على عدد كبير من المطورين الذين يقومون بتطوير أعداداً ضخمة من البرمجيات. وهذا يعني أنَّ مكتبة واحدة من برمجية مطورة بلغة PHP قد تستخدم أسماءَ لكائنات مستعملة في مكتبة أخرى، أي قد يحدث تضارب في التَّسْميات. عندما تُستخدم عدة مكاتب في نفس فضاء الاسم (namespace) قد يسبب ذلك (التضارب في التسميات) بعض المشاكل.
فضاءات الأسماء Namespaces تحل هذه المشكلة. كما هو مُوضحٌ في مرجع لغة PHP، أسماء الفضاءات يمكن تشبيهها بمجلدات النظام حيث يمكن لملفين يحملان نفس الاسم أن يوجدا في مُجلدين مختلفين. كذلك بالنسبة لكائنات PHP فيمكن لكائنين حمل نفس الاسم ولكن يجب لأن يكونا في فضاءين مختلفين.
فمن المهم أن تستخدم هذه الفضاءات في عملك، بالتحديد إذا كنت تنوي مشاركة هذا العمل مع مطورين آخرين. فهذا يمنع حدوث التضارب فيما بين المكتبات المتعددة.
هنالك طريقة موصى بها لاستخدام فضاءات الاسماء وهي مدرجة PSR-4، وتهدف إلى تحديد نمط قياسي لكل ملف وكائن و فضاء اسم لسهولة الاستخدام وإمكانية الإدراج والبدء بالاستخدام المباشر للمكتبات.
في أكتوبر 20014 PHP-FIG قامت بإهمال وإيقاف العمل بطريقة الإدراج التلقائي القياسية بالرمز PSR-0. كلا الإصدارين PSR-0 و PSR-4 ما يزالان صالحين للاستخدام. ولكن الثاني يتطلب إصدار PHP 5.3 لذا العديد من المشاريع المبرمجة على إصدار PHP 5.2 تستخدم PSR-0.
إذا كنت تنوي استخدام الإستدعاء التلقائي في تطبيقك أو حزمتك، حينها يجب أن تلقي نظرة على التوصية القياسية PSR-4.
مكتبة PHP القياسية (Standard PHP Library إختصارا SPL) هي مكتبة مدمجة مع PHP، توفر مجموعة من الكائنات (classes) والواجهات (interfaces). صُمِّمت هذه المكتبة لتلبي الإحتياجات الأساسية من كائنات هيكلة البيانات (المكدسات، الصفوف، الأكوام وغيرها)، ودوال تكرار تختصر عمل هيكلة البيانات في كائناتك التي تطبق واجهات المكتبة القياسية.
صُمِّمَت لغة PHP لكتابة تطبيقات الويب، ولكن من المفيد أيضاً التعامل مع برامج واجهة سطور الأوامر (CLI). برامج PHP المبنية للعمل على سطور الأوامر تساعد على أداء مهام معتادة مثل تجربة ونشر وإدارة البرامج بصورة تلقائية.
تطبيقات PHP التي تعمل على واجهة سطور الأوامر هي برامج قوية لأنها تستخدم مصدر البرنامج مباشرة دون الحاجة لتطوير واجهة ويب مرئية ومَحْمِيَّة. ولكن تأكد من عدم وضع تطبيقك الذي يعمل بواجهة سطور الأوامر في مجلد موقعك (حيث يمكن للجميع رؤيته)!
جرب تشغيل أمر PHP هذا من واجهة سطور الأوامر:
يدل خيار -i
على طباعة بيانات ضبط PHP كما تنفذه دالة phpinfo()
تماماً.
أيضاً خيار -a
يوفر أوامر تفاعلية مماثلة لشبيهاتها عند ruby IRB و python interactive shell. هنالك عدد من الأوامر والخيارات المفيدة
التي يمكنك الاطلاع عليها أيضاً command line options.
لنقم بتجربة كتابة برنامج ترحيبي سهل بطريقة واجهة سطور الأوامر، قم بإنشاء ملف باسم hello.php
ثم قم بكتابة الآتي:
تقوم PHP بإنشاء متغيرين خاصين بناءَ على القيم التي يعمل بها تطبيقك.
$argc
وهو متغير رقمي يحتوي على عدد القيم.
$argv
وهو متغير به مصفوفة تحوتي على قيمة كل من القيم.
دائما ما يكون الخيار الأول من القيم هو اسم ملف PHP المراد تنفيذه وفي هذه الحالة هو الملف hello.php
.
تستخدم دالة exit()
دون قيمة صفرية لإعلام منفذ الأوامر بأن الأمر قد فشل!.
يمكن الإطلاع على شفرات الخروج من هنا.
لتنفيذ الملف، قم بفتح نافذة تنفيذ سطور الأوامر ثم قم بكتابة الآتي:
أحد أهم أدوات التطوير هو: مَصَحح فعال! فهو يتيح لك تعقب تنفيذ المصدر البرمجي ومراقبة محتواه وتدفق عمليته. Xdebug هو مُصَحح لغة PHP، يمكن استعماله من خلال بيئة التطوير المتكاملة (IDE) لتوفير نقاط توقف وتعقب التدفق. أيضاً يتيح لأدوات مثل PHPUnit و KCacheGrind عمل تغطية شاملة على المصدر البرمجي لفحصه وتحليله.
إذا كنت تلجأ لاستخدام var_dump()
أو print_r()
، لكنهما لم تفيان بالغرض، إذا عليك أن تستخدم مُصَححا حينها!
تنصيب Xdebug قد يكون معَقَّدا بعض الشيء، ولكن واحدة من أهم مميزاته هو التصحيح عن بعد (Remote Debugging)، فإذا كنت تقوم بتطوير برنامجك في بيئة محلية ثم تقوم بتجربته داخل نظام افتراضي أو في خادم آخر عندها التصحيح عن بعد هو الخيار الذي يسهل عليك المتابعة والتصحيح بالطريقة الصحيحة.
يمكنك تعديل Apache VHost أو ملف .htaccess وإعطاؤه القيم الآتية:
كل من “remote host” و”remote port” يعبران عن بيانات جهازك الخاص والمنفذ الذي تتعامل به بيئة التطوير المتكاملة (IDE) للاستماع إليه. الآن كل ما عليك فعله هو أن تضع برنامج بيئة التطوير IDE لديك على وضعية استماع الإتصالات (Listen for connections Mode) ثم عرض الصفحة باستخدام URL:
http://your-website.example.com/index.php?XDEBUG_SESSION_START=1
سوف يعترض برنامج التطوير لديك الحالة الحالية لتنفيذ المصدر، مما يتيح لك أن تضع نقاط توقف والاطلاع ومتابعة القيم في الذاكرة.
أدوات التصحيح المرئية تسهل استخدامها مع الشفرة، والتحقق من المتغيرات، وتنفيذ الشفرة مباشرة. العديد من برامج بيئة التطوير IDE لديها إضافة مدمجة تدعم أدوات التصحيح المرئية ومتوافقة مع xDebug. MacDGBp هو أداة مجانية ومفتوحة المصدر قائمة بذاتها تعمل على نظام التشغيل Mac.
لغة البرمجة PHP لديها العديد من المكتبات وأطر العمل والمحتويات التي تستطيع اختيار أحدها. ربما قد تستخدم بعضا منها في عملك أو مشروعك، تلك الإضافات تُسَمَّى توابع المشروع. منذ عهد قريب لم تكن لغة البرمجة PHP تملك طريقة مثلى لإدارة تلك التوابع. حتى إن قمت بإدارتها يدويا، مازلت تحتاج ان تعير انتباهاً لتحميلها آليا (autoloaders). ولكن هذا الأمر لم يعد يشكل مشكلة.
حتى الآن رائدي أنظمَة إدارة التوابع في لغة البرمجة PHP هما Composer و PEAR. Composer حالياً هو الأكثر شهرة، لكن لفترة طويلة من الزمن كان PEAR هو النظام الأساسي لإدارة التوابع في PHP. من الجيد معرفة تفاصيل تاريخ PEAR، لأنه يمكن الرجوع إليها ولو لم تستخدمها..
يعتبر Composer أداة ممتازة لإدارة توابع لغة PHP. كل ما عليك هو أن تضع قائمة بالتوابع في ملف composer.json
وببعض أوامر
سهلة سيقوم Composer بتنزيل كل توابع مشروعك بالإضافة لتنصيب وضبط ملف إدراج تلقائي autoload.
يعتبر Composer مماثل لـ NPM المستخدم في node.js، أو Bundler المستخدم في Ruby.
يوجد الكثير من مكتبات لغة PHP متوافقة مع Composer وجاهزة للاستخدام مع مشروعك. هذه المكتبات أو «الحزم» مدرجة في Packagist، المستودع الحصري لكل مكتبات لغة PHP المتوافقة مع Composer.
الطريقة الآمنة لتحميل Composer هي عن طريق التعليمات الرسمية. سيتم التحقق من ملفات التنصيب كونها سليمة ولم يتم التلاعب بها. يقوم ملف التنصيب بتنصيب Composer محلياً في مجلد العمل الحالي.
ننصح بتنصيبه للإتاحة العامة (مثلا نسخة واحدة في /usr/local/bin
)، للقيام بذلك قم بتنفيذ:
ملاحظة: إذا فشل الأمر السابق بسبب صلاحيات قم بتشغيل الأمر mv
مرة أخرى بكتابة الأمر sudo
قبله.
لتشغيل Composer الذي تم تنصيبه محلياً قم باستخدام php composer.phar
وعامةً قم باستخدام composer
فقط.
بالنسبة لمستخدمي نظام التشغيل Windows الطريقة الأسهل هي استخدام ملف تنصيب ComposerSetup، حيث يقوم بتنصيبه بشكل عام على النظام، ويقوم بضبط متغيرات $PATH
حتى تتمكن من استدعاء الأمر composer
فقط من شاشة سطور الأوامر من أي مجلد في النظام.
تنصيب Composer يدوياً هو عملية متقدمة، لذلك هناك العديد من الأسباب تجعل المُطَوِّر يقوم باستخدام هذه الطريقة بدلاً عن الطريقة التلقائية التقليدية. فالطريقة التقليدية التلقائية تقوم بفحص إصدار PHP الحالي لتقوم بالتَّأكد من الآتي:
.phar
بصورة صحيحة.php.ini
.في المقابل الطريقة التقليدية لا تقوم بأي من العمليات المذكورة آنفاً، يتوجب عليك أن تقوم ببعض أو كل العمليات يدوياً، لتنصيب Composer يدويا قم بالآتي:
المجلد $HOME/local/bin
(أو المجلد الذي تختاره) يجب أن يكون مُدْرَجًا في متغيرات $PATH
. وهكذا يمكن الوصول إلى الأمر composer
من أي مكان (في نظام التشغيل).
عند استخدام طريقة اليدوية ستتغير طريقة الاستخدام التي قد تجدها في بعض المراجع php composer.phar install
ليكتب بدلاً منها الآتي:
في القسم التالي سوف نفترض أنك قمت بتنصيب Composer بشكل عام في النظام.
يقوم Composer بتتبع وإدارة توابع مشروعك عن طريق ملف يسمى composer.json
. يمكنك إدارة هذا الملف يدوياً باستخدام أي محرر نصوص، أو استخدام Composer لإنجاز هذه العملية. يقوم الأمر composer require
بإضافة تابع إلى مشروعك، فإذا لم يكن ملف composer.json
موجوداً سيقوم تلقائياً بإنشائه.
مثال لإدراج مكتبة Twig كتابع لمشروعك.
عوضاً عن ذلك يمكنك تنفيذ الأمر composer init
الذي سيساعدك لإنشاء ملف composer.json
بالكامل ليتناسب مع مشروعك. ويمكنك أيضاً بعد إنشاء ملف composer.json
أن تُخْبِر Composer بأن يقوم بتحميل وتنصيب التوابع في مجلد vendor/
. وهذا ينطبق أيضاً على المشاريع والمكتبات التي تقوم بتنزيلها ويوجد معها الملف composer.json
.
بعدها، قم بإضافة هذا السطر إلى ملف برنامجك الأساسي، حتى يتمكن من إعلام PHP لتستخدم المدرج التلقائي autoloader التابع لـ Composer ليدرج التوابع لمشروعك.
يمكنك الآن استخدام توابع مشروعك وسيتم إدراجها تلقائياً باستخدام autoloader.
يقوم Composer بإنشاء ملف باسم composer.lock
حيث يقوم بحفظ أرقام إصدارات كل تابع يقوم بتحميله عند تنفيذ الأمر composer install
أول مرة. إذا كنت تشارك مشروعك مع مطورين آخرين وملف composer.lock
هو جزء من ملفاتك، فعندما يقوم أحدهم بتنفيذ الأمر composer install
سوف يحصل على نفس الإصدارات الموجودة لديك.
لتحديث التوابع قم بتنفيذ الأمر composer update
. لا تقم بالتحديث عند التركيب على بيئة العمل النهائية، ولكن قم بالتنصيب باستخدام composer install
وإلا سينتهي بك المطاف بأن يكون هناك اختلاف في إصدارات الحزم.
تكون هذه العملية مفيدة عندما تكون متطلباتك من التوابع محددة بمرونة، فمثلا تتطلب لمشروعك تابع بالإصدار ~1.8
بمعنى «كل الإصدارات الأحدث من 1.8.0، والأقل من 2.0.x-dev». يمكنك أيضاً استخدام *
1.8.*
لتحديد الكل من خانة واحدة.
فالآن عند تنفيذ الأمر composer update
سيقوم Composer بتحديث كل توابعك إلى النسخة الأحدث بناءً على ما قد حَدَّدته سلفاً كمطلب.
لكي تصل إليك تنبيهات عند صدور إصدارات جديدة من التوابع يمكنك التسجيل في VersionEye، وهي خدمة يمكنها متابعة حسابك في كل من
GitHub و BitBucket للبحث داخل ملفات composer.json
، وتقوم بإرسال بريد إلكتروني عند صدور تحديثات جديدة.
Security Advisories Checker هي خدمة وأداة تعمل على سطور الأوامر، حيث تقوم باختبار ملف composer.lock
وتقوم بإخبارك إذا ما كان هنالك حاجة لتحديث أي من التوابع.
يمكن لـ Composer التَّحكم في التوابع وملفاتها التنفيذية أيضاً. طريقة الاستخدام واضحة جداً، كل ما عليك فعله هو إدراج كلمة global
قبل تنفيذ الأمر. مثلا إذا كنت تريد تنصيب الأداة PHPUnit واستخدامها بشكل عام في نظامك قم بتنفيذ هذا الأمر:
هذا الأمر سيقوم بإنشاء مجلد في ~/.composer
حيث يقوم بوضع كل التوابع العامة هناك. ولكي تقوم بتنفيذ أوامر وعمليات تلك التوابع
من أي مكان، قم بإدراج مسار المجلد ~/.composer/vendor/bin
إلى متغير $PATH
في النظام لديك.
PEAR هو أقدم برنامج لإدارة التوابع في PHP استمتع به كثير من المطورين. فهو يقوم بنفس وظائف Composer تماما ولكن مع بعض الإختلافات الملحوظة.
يحتاج PEAR أن يكون لكل حزمة أو تابع هيكلة محددة، حيث يتوجب على كاتب الحزمة أو التابع أن يقوم بتجهيزها لكي يتم استخدامها عن طريق PEAR. استخدام مشروع غير مجهز للعمل مع PEAR هو شيء مستحيل.
يقوم PEAR بتنصيب كل التوابع بشكل عام، مما يعني بعد تنصيب التوابع مرة واحدة تكون متوفرة بشكل عام لكل المشاريع على نفس الخادم. قد يكون هذا أمرا جيدا إذا كانت عدة مشاريع تعتمد نفس التوابع بنفس الإصدارات ولكن هذا قد يحدث مشاكل مثل تضارب الإعتمادية على إصدارات مختلفة بين المشاريع!
يمكنك تنصيب PEAR عن طريق تحميل ملف .phar
ثم تشغيله. يحتوي دليل PEAR على تفاصيل التنصيب لكل نظام تشغيل تعليمات التنصيب.
إذا كنت تستخدم Linux، يمكن أن تطلع على مدير الحزم لديك. Debian و Ubuntu لديهما الحزمة عن طريق apt php-pear
.
إذا كانت الحزمة أو التابع مدرجا في قائمة حزم PEAR، يمكنك التنصيب باستخدام الاسم الحصري:
إذا كانت الحزمة مستضافة على قناة أخرى، ما عليك سوى القيام بتنفيذ استكشاف القناة discover
أولا، ثم تحديدها عند التنصيب.
اطلع على دليل استخدام القنوات لمزيد من التفاصيل في هذا الموضوع.
إذا كنت تستخدم Composer عندها يمكنك تنصيب بعض حزم PEAR أيضاً، يمكن استخدام Composer لإدارة توابع وحزم PEAR.
مثال لتنصيب كود مصدري من pear2.php.net
:
الجزء الأول "repositories"
سوف يستخدم من قبل Composer لكي يقوم بتهيئة (أو استكشاف “discover” بمصطلح PEAR) مستودع PEAR.
الجزء الثاني "require"
يقوم بإضافة لاحقة لاسم الحزمة هكذا:
pear-channel/Package
تم برمجة اللاحقة “pear” يدوياً للحد من حدوث تضاربات، فقد تستخدم قناة PEAR نفس الاسم لحزمة أو تابع مختلف للموزع مثلا، عندها اسم القناة القصير (أو العنوان الكامل URL) يُستخدم للإرشاد إلى أي قناة تَتْبَع هذه الحزمة.
بعد تنصيب هذا التابع أعلاه سيكون متوفرا في مجلد vendor
ويمكن إدراجه تلقائياً باستخدام Composer autoloader:
vendor/pear-pear2.php.net/PEAR2_HTTP_Request/pear2/HTTP/Request.php
لاستخدام حزمة PEAR هذه قم باستخدامها هكذا:
PHP هي لغة واسعة تتيح لمُبَرمجي جميع المستويات إمكانية إنتاج برمجيات، ليس بسرعة فقط، بل بكفاءة أيضاً! لكن كلما تعمقنا في اللغة نكتشف أننا قد نسينا الأساسيات التي تعلمناها منذ البداية (أو تغاضينا عنها) لكي نختصر الزمن أو نسلك طريقاً مختصراً لأداء المهام بممارسات سيئة. هذا الفصل يهدف لتجنب هذا النوع من المشاكل المعتادة وتذكير المبرمجين بهذه الممارسات الأساسية في إطار لغة PHP.
يوجد صنف (أو class) في لغة البرمجة PHP يُسَمَّى DateTime يساعد في عمليات قراءة وكتابة ومقارنة وحساب الوقت والتاريخ. هناك العديد من الدوال المتعلقة بعمليات الوقت والتاريخ مضمنة في لغة البرمجة PHP، ولكن DateTime يوفرها بواجهة كائنية (أو شيئية Object-Oriented) للعديد من الاستخدامات. يمكن لهذا الصنف التعامل مع النِّطَاقات الزَّمنية، ولكن هذا غير مُدْرَج في هذا الشرح التعريفي القصير.
لكي نبدأ باستخدام DateTime، قم بتحويل صيغة كاملة صحيحة لتاريخ وزمن بصيغة نصية إلى الصنف باستخدام الدالة المصنِعة createFromFormat()
أو يمكنك البدء بإنشاء كائن جديد باستخدام new DateTime
وينتج من تنفيذ هذا الأخير الوقت والزمن الحاليين. يمكن استخدام الدالة format()
لتحويل DateTime إلى صيغة نصية مرة أخرى للتمكن من طباعتها مثلا.
يمكن إجراء عمليات حسابية باستخدام DateTime وذلك باستخدام صنف DateInterval.
يحتوي صنف DateTime على دوال مثل add()
و sub()
التي تَسْتخدم مُخْرَجات صنف DateInterval كمعطيات.
لا تقم مطلقاً بكتابة دوال للقيام بعمليةِ حسابِ الثواني في اليوم أو حساب الفترة النهارية أو حتى حساب فرق التوقيت الزمني، ولا تقم باستخدام بدائل أخرى بشكل عام. اسْتَخْدِم DateInterval عوضاً عن ذلك.
للقيام بحساب فَرْقِ التاريخ بين تاريخين قم باستخدام الدالة diff()
فهي تقوم بإرجاع DateInterval وعندها يمكن عرضه واستخدامه بسهولة.
يمكن لكائن DateTime أن يُستخدم لإجراء عملية مقارنة بالطريقة التقليدية باستخدام:
المثال الأخير يقوم بشرح صنف DatePeriod الذي يستخدم لعمليات التكرار للأحداث المتكررة. يمكنه أخذ كائني DateTime كمعطيات البداية والنهاية وكائن DateInterval لتحديد الحدث الزمني ليقوم بإرجاع كل الأحداث المتطابقة بين التاريخين!
من لواحق واجهات البرمجة (API) المشهورة للغة PHP Carbon. تقوم بوراثة كل شيء من صنف DateTime، لتَقُوم بتعديل طفيف على الشفرة البرمجية، ولكن بخواص أخرى إضافية تضم ميزة التعريب بالإضافة لعمليات إضافة وطرح التاريخ بصيغ مختلفة مما يعني أنه يمكن اختبار التطبيق باستخدام تاريخ من اختيارك.
عندما تقوم ببناء برنامج من المفيد أن تستخدم الممارسات البرمجية المعروفة أثناء الكتابة، واتباع النماذج المعروفة للهيكلة العامة للمشروع. استخدام هذه النماذج يسهل عملية إدارة المصدر ويسهل على مبرمجين فهم كيفية عمل الأشياء سوياً.
إذا كنت تستخدم إطار عمل Framework عندها سيكون هيكل مشروعك في إطاره. عندها الكثير من القرارات الهيكلية قد تم اتخاذها لك مسبقاً ولكن ما يزال عليك أن تختار النماذج المثلى لتتبعها في المصدر الذي تقوم بكتابته لبناء المشروع في هذا الإطار. إذا كنت لا تستخدم إطار عمل لبناء برنامج يجب عليك أن تجد وتستخدم النماذج المثلى التي تنطبق على نوع وحجم البرنامج الذي تقوم ببنائه.
هذا الفصل تم كتابته من قبل أليكس كابال في أفضل ممارسات PHP حيث تم استخدامها كأساس لنصائحنا للعمل بترميز UTF-8.
حتى الآن لم تقم PHP بدعم ترميز Unicode في مستوياتها الأساسية. هناك طرق للتَّأكد من أن النصوص قد تمت معالجتها بالترميز UTF-8، ولكنها عملية ليست سهلة وتحتاج الكثير من البحث والتنقيب في كل مستويات تطبيق الويب، ابتداءً من HTML إلى SQL وحتى PHP. سوف نقوم بإيجاز نبذة عن تطبيقات عملية.
لا تحتاج عمليات النصوص، مثل دمج النصوص وتعيين قيم نصية إلى متغيرات، إلى أي شيء خاص لكي تتبع ترميز UTF-8.
لكن كثيرا من دوال النصوص مثل strpos()
وstrlen()
تحتاج عناية خاصة.
هذه الدوال عادة ما تكون لها نظيراتها باللاَّحِقة mb_*
مثلاً: mb_strpos()
وmb_strlen()
. هذه الدوال عن طريق إضافة Multibyte String Extension وهي مُخَصَّصَة للتعامل مع النصوص بترميز Unicode.
يجب عليك أن تستخدم دوال mb_*
كلما أردت التَّعامل مع نص بترميز Unicode. مثلا إذا قمت باستخدام substr()
على نص بترميز UTF-8 هناك احتمال أَنَّ النتيجة ستحتوي رموزَا مشوَّهة. في هذه الحالة الطريقة الصحيحة هي استخدام دالة تأخذ النصوص متعددة البايت بالإعتبار (Multibyte) mb_substr()
.
الصعوبة تَكْمُن في تَذَكُّر استخدام دوال mb_*
دائماً عوضاً عن الدوال الأصلية. إذا قمت بنسيان ذلك ذات مرة فأي نص بترميز Unicode يكون مهدَّدًا بالتشوه في أي عملية لاحقة قد تطرأ عليه، مما يعني نتائج غير محمودة!
ليس كل دوال النصوص لديها معالجات في دوال mb_*
. إذَا لم يكن هناك واحدة توفر لك الاستخدام المطلوب فأنت غير محظوظ!
يجب استخدام الدَّالة mb_internal_encoding()
في بداية كل مصدر PHP تقوم بكتابته (كملف الإستدعاء الرئيس لبقية الملفات مثلاً)،
تليها دالة mb_http_output()
إذا كنت ستقوم بطباعة نص على المتصفح.
تعيين الترميز بشكل صريح في كل نصوصك يَقِيك الكثير مِمَّا لا تُحمد عقباه خلال عملية التطوير.
إضافةً إلى ذلك هناك العديد من الدوال المدمجة تتيح إدارة النصوص عبر معطيات اختيارية لتحديد ترميز النصوص. عندها يجب عليك تحديد
UTF-8 عندما يكون هذا الخيار متاحاً. مثلا دالة htmlentities()
لديها معطى اختياري لتحديد الترميز، سيتوجب عليك دائما تحديد
ترميز UTF-8 للتعامل مع النصوص.
ملاحظة: htmlentities()
وhtmlspecialchars()
تستخدمان الترميز UTF-8 كترميز نصوص افتراضي منذ إصدار PHP 5.4.0.
أخيراً، إذا كنت تقوم ببناء تطبيق تنوي نشره وكنت غير متأكد من أن إضافة mbstring
ستكون متوفرة أم لا، يجب عليك التفكير في استخدام حزمة Composer تسمى patchwork/utf8. ستقوم هذه الحزمة بإتاحة استخدام mbstring
إذا كانت متوفرة، أو تقوم باستخدام الدوال الإفتراضية إذا لم تكن الأخرى متوفرة.
إذا كان تطبيقك يقوم بالوصول إلى قاعدة البيانات MySQL، عندها هناك احتمال أنَّ النصوص تُحفظ بترميز غير UTF-8 في قاعدة البيانات حتى ولو اتبعت كل التحذيرات أعلاه!
لكي تكون متأكداً من أن النصوص تُنتقل من PHP إلى MySQL بترميز UTF-8، تَأَكَّد من أن جميع الجداول في قاعدة البيانات قد تم ضبط ترميزها لتسخدم الترميز utf8mb4
في كل من الترميز والترتيب (Character set and Collation)، وأن تقوم باستخدام utf8mb4
عند الاتصال باستخدام PDO، قم بالإطلاع على المثال أدناه فهو هام جدا.
ملاحظة: يجب استخدام ترميز utf8mb4
لدعمِ كاملِ لترميز UTF-8 وليس الترميز utf8
! أكمل القراءة لمعرفة السبب.
استخدم الدَّالة mb_http_output()
للتَّأكد من أن تطبيقك يطبع نصوصا بترميز UTF-8 على المتصفح.
سيلزم عندها إخبار المتصفح -باستخدام HTTP Response- أن هذه الصفحة يجب أن تعتبر مُرَمَّزة باستخدام UTF-8.
سابقاً كان يتم إدراج هذا الإجراء عن طريق إدراج charset في وسم <meta>
بداخل وسم <head>
في الصفحة. هذا الإجراء سليم تماماً ولكن إضافة Content-Type
كترويسة (header) هو عملياً أكثر سرعة.
Disclaimer for newcomers: i18n and l10n are numeronyms, a kind of abbreviation where numbers are used to shorten words - in our case, internationalization becomes i18n and localization, l10n.
First of all, we need to define those two similar concepts and other related things:
The easiest way to internationalize PHP software is by using array files and using those strings in templates, such as
<h1><?=$TRANS['title_about_page']?></h1>
. This is, however, hardly a recommended way for serious projects, as it poses
some maintenance issues along the road - some might appear in the very beginning, such as pluralization. So, please,
don’t try this if your project will contain more than a couple of pages.
The most classic way and often taken as reference for i18n and l10n is a Unix tool called gettext
. It dates
back to 1995 and is still a complete implementation for translating software. It is pretty easy to get running, while
it still sports powerful supporting tools. It’s about Gettext we will be talking here. Also, to help you not get messy
over the command-line, we will be presenting a great GUI application that can be used to easily update your l10n source
files.
There are common libraries used that support Gettext and other implementations of i18n. Some of them may seem easier to install or sport additional features or i18n file formats. In this document, we focus on the tools provided with the PHP core, but here we list others for completion:
gettext
command), and can also export
to other formats besides .mo/.po
files. Can be useful if you need to integrate your translation files into other parts
of the system, like a JavaScript interface.strtr()
internally.Other frameworks also include i18n modules, but those are not available outside of their codebases:
@lang
helper for template files.Intl
extension, available since PHP 5.3, and based on the ICU project; this enables Yii to run powerful
replacements, like spelling out numbers, formatting dates, times, intervals, currency, and ordinals.If you decide to go for one of the libraries that provide no extractors, you may want to use the gettext formats, so you can use the original gettext toolchain (including Poedit) as described in the rest of the chapter.
You might need to install Gettext and the related PHP library by using your package manager, like apt-get
or yum
.
After installed, enable it by adding extension=gettext.so
(Linux/Unix) or extension=php_gettext.dll
(Windows) to
your php.ini
.
Here we will also be using Poedit to create translation files. You will probably find it in your system’s package manager; it’s available for Unix, Mac, and Windows, and can be downloaded for free on their website as well.
There are three files you usually deal with while working with gettext. The main ones are PO (Portable Object) and MO (Machine Object) files, the first being a list of readable “translated objects” and the second, the corresponding binary to be interpreted by gettext when doing localization. There’s also a POT (Template) file, that simply contains all existing keys from your source files, and can be used as a guide to generate and update all PO files. Those template files are not mandatory: depending on the tool you’re using to do l10n, you can go just fine with only PO/MO files. You’ll always have one pair of PO/MO files per language and region, but only one POT per domain.
There are some cases, in big projects, where you might need to separate translations when the same words convey
different meaning given a context. In those cases, you split them into different domains. They’re basically named
groups of POT/PO/MO files, where the filename is the said translation domain. Small and medium-sized projects usually,
for simplicity, use only one domain; its name is arbitrary, but we will be using “main” for our code samples.
In Symfony projects, for example, domains are used to separate the translation for validation messages.
A locale is simply a code that identifies one version of a language. It’s defined following the ISO 639-1 and ISO 3166-1 alpha-2 specs: two lower-case letters for the language, optionally followed by an underline and two upper-case letters identifying the country or regional code. For rare languages, three letters are used.
For some speakers, the country part may seem redundant. In fact, some languages have dialects in different
countries, such as Austrian German (de_AT
) or Brazilian Portuguese (pt_BR
). The second part is used to distinguish
between those dialects - when it’s not present, it’s taken as a “generic” or “hybrid” version of the language.
To use Gettext, we will need to adhere to a specific structure of folders. First, you’ll need to select an arbitrary
root for your l10n files in your source repository. Inside it, you’ll have a folder for each needed locale, and a fixed
LC_MESSAGES
folder that will contain all your PO/MO pairs. Example:
As we said in the introduction, different languages might sport different plural rules. However, gettext saves us from
this trouble once again. When creating a new .po
file, you’ll have to declare the plural rules for that
language, and translated pieces that are plural-sensitive will have a different form for each of those rules. When
calling Gettext in code, you’ll have to specify the number related to the sentence, and it will work out the correct
form to use - even using string substitution if needed.
Plural rules include the number of plurals available and a boolean test with n
that would define in which rule the
given number falls (starting the count with 0). For example:
nplurals=1; plural=0
- only one rulenplurals=2; plural=(n != 1);
- two rules, first if N is one, second rule otherwisenplurals=2; plural=(n > 1);
- two rules, second if N is bigger than one, first otherwiseNow that you understood the basis of how plural rules works - and if you didn’t, please look at a deeper explanation on the LingoHub tutorial -, you might want to copy the ones you need from a list instead of writing them by hand.
When calling out Gettext to do localization on sentences with counters, you’ll have to give him the
related number as well. Gettext will work out what rule should be in effect and use the correct localized version.
You will need to include in the .po
file a different sentence for each plural rule defined.
After all that theory, let’s get a little practical. Here’s an excerpt of a .po
file - don’t mind with its format,
but instead the overall content, you’ll learn how to edit it easily later:
The first section works like a header, having the msgid
and msgstr
especially empty. It describes the file encoding,
plural forms and other things that are less relevant.
The second section translates a simple string from English to
Brazilian Portuguese, and the third does the same, but leveraging string replacement from sprintf
so the
translation may contain the user name and visit date.
The last section is a sample of pluralization forms, displaying
the singular and plural version as msgid
in English and their corresponding translations as msgstr
0 and 1
(following the number given by the plural rule). There, string replacement is used as well so the number can be seen
directly in the sentence, by using %d
. The plural forms always have two msgid
(singular and plural), so it’s
advised to not use a complex language as the source of translation.
As you might have noticed, we’re using as source ID the actual sentence in English. That msgid
is the same used
throughout all your .po
files, meaning other languages will have the same format and the same msgid
fields but
translated msgstr
lines.
Talking about translation keys, there are two main “schools” here:
msgid
as a real sentence.msgid
;msgid
across several language files.msgid
as a unique, structured key.en.po
file, that
translators would read to understand what to write in fr.po
for instance.top_menu.welcome
instead of Hello there, User!
on the said untranslated French page). That’s good it as would force translation to be complete before publishing -
but bad as translation issues would be really awful in the interface. Some libraries, though, include an option to
specify a given language as “fallback”, having a similar behavior as the other approach.The Gettext manual favors the first approach as, in general, it’s easier for translators and users in case of trouble. That’s how we will be working here as well. However, the Symfony documentation favors keyword-based translation, to allow for independent changes of all translations without affecting templates as well.
In a common application, you would use some Gettext functions while writing static text in your pages. Those sentences
would then appear in .po
files, get translated, compiled into .mo
files and then, used by Gettext when rendering
the actual interface. Given that, let’s tie together what we have discussed so far in a step-by-step example:
gettext()
simply translates a msgid
into its corresponding msgstr
for a given language. There’s also
the shorthand function _()
that works the same way;ngettext()
does the same but with plural rules;dgettext()
and dngettext()
, that allows you to override the domain for a single
call. More on domain configuration in the next example.i18n_setup.php
as used above), selecting the correct locale and configuring GettextTo make matters easier - and one of the powerful advantages Gettext has over custom framework i18n packages - is its custom file type. “Oh man, that’s quite hard to understand and edit by hand, a simple array would be easier!” Make no mistake, applications like Poedit are here to help - a lot. You can get the program from their website, it’s free and available for all platforms. It’s a pretty easy tool to get used to, and a very powerful one at the same time - using all powerful features Gettext has available.
In the first run, you should select “File > New Catalog” from the menu. There you’ll have a small screen where we will set the terrain so everything else runs smoothly. You’ll be able to find those settings later through “Catalog > Properties”:
.po
file header;en_US
or pt_BR
;gettext()
(and siblings) will happen - this
is usually your templates folder(s)gettext()
calls look like in several programming
languages, but you might as well create your own translation forms. This will be discussed later in the “Tips” section.After setting those points you’ll be prompted to save the file - using that directory structure we mentioned as well,
and then it will run a scan through your source files to find the localization calls. They’ll be fed empty into the
translation table, and you’ll start typing in the localized versions of those strings. Save it and a .mo
file will be
(re)compiled into the same folder and ta-dah: your project is internationalized.
As you may have noticed before, there are two main types of localized strings: simple ones and the ones with plural
forms. The first ones have simply two boxes: source and localized string. The source string can’t be modified as
Gettext/Poedit do not include the powers to alter your source files - you should change the source itself and rescan
the files. Tip: you may right-click a translation line and it will hint you with the source files and lines where that
string is being used.
On the other hand, plural form strings include two boxes to show the two source strings, and tabs so you can configure
the different final forms.
Whenever you change your sources and need to update the translations, just hit Refresh and Poedit will rescan the code, removing non-existent entries, merging the ones that changed and adding new ones. It may also try to guess some translations, based on other ones you did. Those guesses and the changed entries will receive a “Fuzzy” marker, indicating it needs review, being highlighted in the list. It’s also useful if you have a translation team and someone tries to write something they’re not sure about: just mark Fuzzy and someone else will review later.
Finally, it’s advised to leave “View > Untranslated entries first” marked, as it will help you a lot to not forget any entry. From that menu, you can also open parts of the UI that allow you to leave contextual information for translators if needed.
If you’re running PHP as a module on Apache (mod_php
), you might face issues with the .mo
file being cached. It
happens the first time it’s read, and then, to update it, you might need to restart the server. On Nginx and PHP5 it
usually takes only a couple of page refreshes to refresh the translation cache, and on PHP7 it is rarely needed.
As preferred by many people, it’s easier to use _()
instead of gettext()
. Many custom i18n libraries from
frameworks use something similar to t()
as well, to make translated code shorter. However, that’s the only function
that sports a shortcut. You might want to add in your project some others, such as __()
or _n()
for ngettext()
,
or maybe a fancy _r()
that would join gettext()
and sprintf()
calls. Other libraries, such as
oscarotero’s Gettext also provide helper functions like these.
In those cases, you’ll need to instruct the Gettext utility on how to extract the strings from those new functions.
Don’t be afraid, it’s very easy. It’s just a field in the .po
file, or a Settings screen on Poedit. In the editor,
that option is inside “Catalog > Properties > Source keywords”. You need to include there the specifications of those
new functions, following a specific format:
t()
that simply returns the translation for a string, you can specify it as t
.
Gettext will know the only function argument is the string to be translated;__('one user', '%d users', $number)
, the
specification would be __:1,2
, meaning the first form is the first argument, and the second form is the second
argument. If your number comes as the first argument instead, the spec would be __:2,3
, indicating the first form is
the second argument, and so on.After including those new rules in the .po
file, a new scan will bring in your new strings just as easy as before.
مقتبس من ويكيبيديا الإنجليزية Wikipedia:
حقن التوابع هو تصميم نموذجي برمجي يتيح إزالة التوابع المكتوبة صراحةً ثم جعلها متوفرة للتغيير سواء كان ذلك في مرحلة التشغيل أو في مرحلة البناء.
هذا الإقتباس يجعل هذا المفهوم مُعَقَّدا أكثر مما هو عليه فعلا. عملية حقن تابع هو تجهيز محتوياته وتوابعه سواء باستخدام حقن عند الإنشاء أو تنفيذ الدوال أو في الضبط. إنه بهذه السهولة.
— title: المفهوم الأساسي isChild: true anchor: basic_concept —
يمكن شرح هذا المفهوم باستخدام مثال سَهْل.
لدينا صنف Database
يعتمد على مُحول للتخاطب مع قاعدة البيانات. نقوم بإنشاء المحول في دالة الإنشاء ثم نقوم بحقن ثابت.
هذا يجعل عملية التجربة والإختبار عملية صعبة مما يعني أن الصنف Database
مرتبط بشدة مع المحول.
يمكن إعادة صياغة هذه الشفرة البرمجية لاستخدام حقن التوابع وفك الإرتباط من التوابع:
الآن يمكننا أن نعطي صنف Database
توابعه عن طريق إنشائها بنفسه. ويمكن أيضاً إنشاء دالة تستقبل التابع كقيمة ثم إسنادها مباشرة، أو إذا كان المحول $adapter
في وصف عام public property
عندها يمكن إسناده مباشرةً.
إذا كنت قرأت عن حقن التوابع سابقاً قد يكون لفت انتباهك مصطلح “Inversion of Control” انعكاس التحكم أو “Dependency Inversion Principle” مفهوم عكس تحكم التوابع. هذه المشاكل المعقدة هي ما يقوم حقن التوابع بحلها.
انعكاس التحكم كما يدل عليها الاسم هو إبقاء التحكم التنظيمي بالكامل بمنئى عن العناصر أو الكائنات. في مصطلح حقن التوابع هذا يعني فك الإرتباط مع التوابع وعكس التحكم بهذه التوابع في مكان آخر في النظام.
طوال عدة سنين، أطر النظام في PHP تستخدم عكس التحكم، ولكن يبقى السؤال: أي جزء من التحكم هو الذي تقوم بعكسه؟ وإلى أين؟ مثلا أطر العمل بنموذج MVC تقدم بشكل عام كائن أساسي أو متحكم أساسي يجب على المتحكمات الفرعية الأخرى أن تستمد منه لكي تحصل على وصول لتوابعه. هذا هو عكس التحكم، لكن عوضاً عن فك ارتباط التوابع هذه الطريقة تقوم بترحيلهم.
حقن التوابع يتيح لنا حل هذه المشكلة بسلاسة عن طريق حقن التوابع التي نريد عند الحاجة، دون الحاجة لأي كتابة صريحة لأي تابع في المصدر على الإطلاق.
مفهوم عكس التحكم هو حرف “D” في مجموعة مفاهيم البرمجة الشيئية S.O.L.I.D وينص على أنه يجب “الإعتماد على التجريد، لا على التحجير أو الإنغلاق”. هذا يعني أن التوابع يجب أن تكون واجهات أو مجردات عوضاً عن التطبيقات الجامدة أو المحجرة. عندها يمكننا إعادة صياغة وكتابة المفهوم أعلاه بسهولة:
هنالك عدة فوائد يستفيد منها صنف Database
الآن، فهوالآن يعتمد على واجهة بدلاً من كائن جامد.
ضع بالإعتبار أنك تعمل ضمن فريق وأن أحد الزملاء يقوم بالعمل على المحول. في المثال الأول يجب أن نقوم بانتظار زميلنا حتى يخبرنا بأنه قد انتهى من المحول حتى يتسنى لنا الاعتماد عليه في إختبار الوحدة. الآن التابع هو عبارة عن واجهة يمكننا أن نعتمد عليها باعتبار أن زميلنا سيقوم ببناء المحول وفق الواجهة المحددة.
فائدة أكبر وهي أن هذه الطريقة تجعل المصدر قابل للتطوير. فمثلا بعد سنة قررنا أن نقوم بالترحيل إلى نوع آخر من قواعد البيانات، يمكن أن نقوم بكاتبة محول يتبع شروط الواجهة الأصلية ثم يحقن عوضاً عنه. عندها لا يوجد تعديل أو إعادة صياغة ويمكن أن نجزم بأن ذلك المحول الجديد يتبع الشروط الموضوعة من قبل الواجهة.
— title: الحاويات Containers isChild: true anchor: containers —
أول شيء يجب أن تفهمه عن حاويات حقن التوابع هو أنها تختلف عن عملية حقن التوابع. الحاوية هي أداة تسهيلية تساعدنا في بناء حقن توابع، ولكن يمكن أن يساء ٱستخدامها لبناء (ضد النمذجة) تحديد للخدمة. حقن تابع بصفته محدد خدمة في الصنف يقوم بإنشاء ٱرتباط أقوى للتوابع في داخل الحاوية بدلاً من التابع الذي تستبدله. وتقوم بتعقيد المصدر مما يجعل تجربته صعبة.
معظم أطر العمل الحديثة تقوم بٱستخدام حاويات حقن التوابع بحيث تتيح لك كتابة توابعك جميعها عن طريق الضبط. ما يعني أن هذه الممارسة تمكنك من كتابة مصدر نظيف وغير مرتبط كإطار العمل الذي بُـني عليه.
عادةً ما تقوم بٱستخدام قاعدة بيانات لبرنامجك لتخزين المعلومات. لديك خيارات محدودة للٱتصال والتعامل مع قاعدة البيانات. الطريقة المستحسنة حتى إصدار PHP 5.1.0 هي ٱستخدام لاحقات التشغيل المدمجة مثل mysqli و pgsql و mssql … ألخ.
لاحقات التشغيل المدمجة ممتازة إذا كنت تستخدم قاعدة بيانات واحدة في برنامجك، ولكن مثلاً إذا كنت تستخدم MySQL والقليل من MSSQL، أو ربما تريد أن تتصل مع قاعدة بيانات أوراكل، عندها لن تتمكن من ٱستخدام نفس تلك اللواحق. سوف تحتاج لتعلم طريقة API جديدة لكل لاحقة قاعدة بيانات — وهذا شيء مجهد.
لاحقة mysql هي لاحقة مدمجة في PHP وقد باتت قديمة وتم الٱستغناء عنها وٱستبدالها بلاحقتين أخريين:
لم يتوقف التطوير على اللاحقة mysql منذ زمن بعيد فحسب، بل وقد تم إهمالها منذ إصدار PHP 5.5.0 ثم تم إزالتها حصرياً في أول إصدار من PHP 7.0
لمعرفة ما إذا كان تطبيق ما يعمل بهذه اللاحقة يمكنك البحث باستخدام محرر النصوص لديك عن دوال مثل mysql_connect()
وmysql_query
فإذا ظهرت نتائج بحث إيجابية فهذا يعني أن هذه اللاحقة مستخدمة في التطبيق. وهذا عوضاً عن البحث في ملف
php.ini
للتحقق من وجود اللاحقة.
حتى وإن لم تكن تستخدم إصدار PHP 7.x بعد، عدم الٱهتمام بالتحديث في أقرب فرصة يزيد صعوبة المهمة عندما تحدث الترقية. أفضل حل هو ٱستبدال ٱستخدام mysql بأي من mysqli أو PDO في تطبيقاتك كممارسة أساسية في عملية التطوير حتى لا تضطر لتنفيذها على عجالة في وقت لاحق.
إذا كنت تنوي الترقية من mysql إلى mysqli، هنالك موجهات سهلة تقترح عليك بأن تقوم بالبحث عن mysql_*
واستبدالها بـ mysqli_*
. هذا المقترح مفرط السهولة، ولكنه يفقد العديد من فوائد وخواص تقدمها mysqli مثل ربط القيم، وهي متوفرة أيضاً في PDO.
تعتبر [PDO] مكتبة مجردة للٱتصال بقاعدة البيانات — تم بنائها في PHP منذ الإصدار 5.1.0 — بحيث توفر واجهات ٱتصال عادية للعديد من قواعد البيانات المختلفة. مثلا يمكن ٱستخدام نفس الشفرة المصدرية للٱتصال والعمل بقاعدة بيانات MySQL أو SQLite:
لا تقوم PDO بترجمة أو تحويل الٱستعلامات SQL Queries أو مماثلة الخصائص المفقودة، ولكنها بالفعل تتصل بأكثر من نوع من قواعد البيانات بنفس الوجهة البرمجية API.
للأهمية: PDO
تتيح بسهولة حقن مدخلات خارجية (كالمفاتح ID مثلا) في ٱستعلام SQL Query من دون القلق بشأن تهديدات SQL Injection.
وهذا ممكن بٱستخدام جمل PDO وتقييد وربط القيم PDO Statements.
فلنفترض أن في مصدر PHP نقوم بٱستقبال مفتاح رقمي ID وهو عبارة عن قيمة في ٱستعلام. هذا المفتاح يجب أن يستخدم لٱستخراج بيانات مستخدم من قاعدة البيانات. الطريقة التالية هي الطريقة الخاطئة
للقيام بهذه العملية:
هذا مصدر خاطئ تماماً. فهو يقوم بإدخال قيم خام إلى ٱستعلام SQL. مما يسبب تَعَرُّضك للٱختراق بسهولة باستخدام أسلوب حقن الٱستعلام [SQL Injection]. تصور أن مخترقا قام بإرسال قيمة ID
عن طريق تنفيذ عنوان مثل http://domain.com/?id=1%3BDELETE+FROM+users
.
سوف يقوم بإسناد للمتغير $_GET['id']
القيمة 1;DELETE FROM users
مما يتسبب بحذف جميع سجلات المستخدمين!
عوضاً عن ذلك يجب أن تقوم (بتعقيم) المفتاح ID المدخل بٱستخدام جمل التقييد في PDO.
وهذا مصدر صحيح. يتم ٱستخدام تقييد القيم في جملة PDO. فبدورها تقوم تلقائياً بتعقيم المدخل ID قبل أن تقوم بإدراجه لقاعدة البيانات مما يمنع ٱحتمال هجمات SQL Injection.
عند كتابة عمليات مثل INSERT أو UPDATE، يجب (للأهمية القصوى) أن تقوم بترشيح البيانات أولاً ثم بتعقيمها من العناصر الأخرى مثل (حذف أوسم HTML و JavaScript وغيرها..). سيقوم PDO فقط بتعقيم المدخلات لٱستخدامها في SQL وليس لكي تستخدمها أنت في تطبيقك.
يجب عليك أن تكون على دراية بأن ٱتصال قاعدة البيانات يقوم بٱستخدام مصادر وأنه ليس من الغريب ٱستهلاك هذه المصادر بسبب تلك الٱتصالات التي لم تغلق، ولكن هذا شيء معتاد في الكثير من لغات البرمجة الأخرى. بٱستخدام PDO يمكنك إغلاق الٱتصال فقط بحذف الكائن وذلك للتأكد من أن كل الٱرتباطات قد تم حذفها. مثلاً إسنادها للقيم الفارغة NULL. إذا لم تقم بهذا يدوياً فسوف تقوم PHP تلقائياً بإغلاق هذه الٱتصالات عندما يتم تنفيذ المصدر إلا إذا كنت تستخدم ٱتصالات مستمرة بالطبع.
عندما يبدأ المطورون تَعَلُّم لغة البرمجة PHP للمرة الأولى، عادة ما يقومون بدمج عمليات قواعد البيانات مع الطرح المنطقي، بكتابة مصدر كهذا:
هذه ممارسة سيئة من كل النواحي، فهي صعبة الفحص وتصحيح الأخطاء، وصعبة التجربة، وصعبة القراءة وستقوم أيضاً بإخراج العديد من الحقول التي لم تقم بعمل حد لها.
هنالك العديد من الحلول - سواء كنت تفضل ٱستخدام البرمجة الشيئية OOP أو البرمجة الوظيفية Functional Programming- ما يزال يتوجب عليك أن تقوم بالفصل.
مثال لطريقة بدائية:
هذه بداية جيدة. قم بوضع كل منهما في ملفين مختلفين عندها تحصل على عملية فصل نظيفة.
قم بإنشاء صنف عوضاً عن تلك الطريقة عندها سيكون لديك نموذج “Model”. قم بإنشاء ملف .php
ثم ضع فيه محتوى العرض المنطقي، عندها سيكون لديك العرض “View”، ستلاحظ أنه قريب من نموذج MVC - طريقة معتادة في معمارية البرمجة الشيئية لأغلبية أطر العمل frameworks.
foo.php
models/FooModel.php
views/foo-list.php
هذا التطبيق هو مماثل جداً لمعظم ما تقوم به أطر العمل الحديثة، ولو تشببها قليلا. قد لا تحتاج أن تقوم بهذه الممارسة في كل مرة، ولكن خلط العرض المنطقي والنموذج التفاعلي لقاعدة البيانات من شأنه أن يُكَوِن مشكلة حقيقية إذا ما أردت أن تقوم بٱختبار وحدات unit-test لتطبيقك.
هنالك مصدر في موقع PHPBridge يسمى إنشاء صنف بيانات Creating a Data Class يقوم بتغطية جميع المواضيع المشابهة، من الجيد للمطورين بأن يتعودوا على مفهوم التفاعل مع قواعد البيانات.
العديد من أطر العمل لديها طبقات التجريد الخاصة بها مما قد يجعلها تكون فوق طبقة أو لا PDO. غالباً ما يتم محاكاة خواص لنظام قاعدة بيانات مفقودة في الأخرى عن طريق ربط الٱستعلامات في دوال PHP، وتعطيك نفس التجريد لقاعدة البيانات عوضاً عن مجرد ٱتصال تجريدي كما تفعل PDO. بالطبع سوف هذه الممارسة تحتاج قليلا من الجهد، ولكن إذا كنت تنوي بناء نظام متنقل يمكنه العمل على كل من MySQL و PostgreSQL و SQLite عندها ستقوم بالقليل من الجهد وكتابة بضع السطور البرمجية.
بعض طبقات التجريد تم بنائها بٱستخدام التوصية PSR-0 أو PSR-4 بأسماء فضاء قياسية حتى تتمكن من تنصيب أي تطبيق تريد، مثل:
توفر النمذجة طريقة مناسبة لفصل التحكم المنطقي من العرض المنطقي. تحتوي النماذج على HTML لتطبيقك، وقد تستخدم صيغ أخرى مثل XML. عادة ما تسمى النماذج بالعرض (أو “views”) فهي تمثل المكون الثاني من النموذج المعماري للبرمجة الكائنية (MVC) model–view–controller.
تكمن الفائدة الأساسية لٱستخدام النماذج في إنشاء فصل «نظيف» بين العرض المنطقي وبقية البرنامج. تكون مسؤولية النماذج الوحيدة هي عرض محتوى مهيء. ولا تحمل أي مسؤولية تنفيذ ٱستخراج بيانات أو عمل مهام معقدة. مما يؤدي إلى مصدر شفرة سهل القراءة ومفيدا خاصة في بيئة العمل في فريق عندها يقوم المطورون بكتابة المصدر البرمجي للعمليات التي تنفذ على الخادم server-side (Controller و Models) ويقوم المصممون بالعمل على جانب العميل client-side.
تقوم النماذج أيضا بتطوير تنظيم شكل ومصدر العرض المنطقي. فالنماذج توضع في مجلد العرض (“Views”) كلٌ محدد بملف واحد. هذا الأسلوب يساعد على وجود مصدر قابل للٱستخدام وإعادة الٱستخدام بحيث أنه يتم تقسيم مجموعات المصدر الكبيرة إلى قطع صغيرة وقابلة للٱستخدام، عادة ما تسمى الأجزاء Partials. مثلاً في الموقع هنالك رأس وذيل كل منهما يمكن أن يعرفا كنماذج يمكن إدراج كل منهما قبل وبعد نموذج أي صفحة.
أخيراً، حسب المكتبة التي تقوم بٱستخدامها، يمكن أن توفر بعض النماذج حماية تلقائياً عن طريق ترشيح المحتوى. بعض المكتبات توفر وضع الحماية sand-boxing بحيث أنه مصممي النماذج لديهم وصول فقط للدوال والمتغيرات في القائمة البيضاء أي في القائمة المسموح بها للٱستخدام في النماذج.
نماذج PHP العادية هي عبارة عن النماذج التي تستخدم مصدر PHP لكتابة محتواها. هنالك العديد من الخيارات بما أن PHP هي عبارة عن لغة نمذجة في نفسها. فهذا يعني أنه يمكن دمج مصدر PHP مع مصادر أخرى مثل توسيم HTML. هذا مفيد لمطوري PHP فهو لا يضيف جمل جديدة لتعلمها، وهم يعلمون الدوال المتوفرة لديهم ومحرر النصوص يحتوي على تخطيط PHP والإكمال التلقائي مدمج معه. تصنف نماذج PHP العادية بأنها سريعة فهي لا تتطلب أي عملية تجميع وبناء.
كل أطر العمل الحديثة تقوم بتوظيف شكل من أشكال نظام النمذجة، فالبعض يستخدم نماذج PHP عادية. بعيداً عن أطر العمل، هنالك مكتبات مثل Plates أو Aura.View تقوم بالعمل على نماذج PHP العادية بطريقة أسهل وذلك عن طريق توفير وظائف نمذجة متطورة مثل التوريث والقوالب والإضافات.
باستخدام مكتبة Plates.
باستخدام مكتبة Plates.
بالرغم أن PHP تطورت بطبيعتها لتكون لغة برمجة كائنية، ولكنها لم تتطور بكونها لغة نمذجة. نماذج التجميع مثل Twig وBrainy وSmarty تملأ هذا الفراغ بتوفير صيغ كتابة جديدة تمتلك المواصفات الحقيقة مثل كونها نماذج. ابتداءً من الترشيح التلقائي حتى التوريث وسهولة التحكم في الهياكل، نماذج التجميع قد صممت لكي تكون سهلة الكتابة والقراءة وآمنة للإستخدام. نماذج التجميع يمكن أن تنتشر وتستخدم عبر لغات مختلفة، Mustache هو مثال جيد لهذا. بما أن هذه النماذج تستوجب عملية التجميع فهنالك فرق في الأداء ولكنه فرق طفيف إذا تم استخدام تخزين مؤقت بطريقة جيدة (caching).
*بالرغم أن Smarty يوفر ترشيح تلقائي ولكنه غير مفعل بشكل إفتراضي.
باستخدام مكتبة Twig.
باستخدام مكتبة Twig.
في الكثير من لغات البرمجة التي تعتمد بكثافة على الإستثناءات “Exceptions” عندما يحدث خطأ ما سوف يتم القاء إستثناء. فهذه هي الطريقة المعتمدة لعمل الأشياء، ولكن لغة PHP لا تعتمد بكثافة على الإستثناءات. ولكن توجد إستثناءات بداخلها والعديد من الدوال الجوهرية بدأت فعلياً باستخدام الإستثناءات ثم التعامل بالكائنات، فالعديد من PHP نفسها تحاول ان تواصل العمل بغض النظر عما يحدث، إلا إذا حدث خطأ ما.
مثلاً:
هذه مجرد ملاحظة ، PHP ستواصل العمل ولن تتوقف. وهذا قد يربك المطورين من لغات اخرى معتمدة على الإستثناءات بكثافة، لأنه عند استخدام متغير غير معرف في لغة Python مثلاً سيقوم برمي إستثناء:
الإختلاف الحقيقي فقط هو أن لغة Python سوف تتوقف لأي شي حتى ولو كان صغيراً، إذاً سيكون المبرمج متأكداً جداً من أي مشكلة قد تحدث سيتم إكتشافها، بالمقابل PHP ستواصل قدماً في المعالجة إلا إذا حدث شيء كبير، عندها ستقوم برمي خطأ وتقرير هذا الخطاً.
لدى PHP عدة مستويات لشدة الخطأ. يوجد ثلاث أنو معروفة من أنواع رسائل الخطأ والملاحظات والتحذيرات.
هنالك عدة مستويات مختلفة من الشدة: E_ERROR
و E_NOTICE
و E_WARNING
. الأولى هي الأخطاء الفادحة التي تحدث أثناء
التنفيذ وغالباً ما تسبب فشل في تنفيذ المصدر ويتوجب عليك فحص هذا الخطأ حتى تتمكن من إكمال التنفيذ لأن PHP ستقوم بإيقاف
التنفيذ. الثانية وهي رسائل نصحية تسبب المصدر في ظهورها ربما تتسبب أو قد لا تتسبب في حدوث خطأ اثناء تنفيذ المصدر، ولكن
لن توقف PHP التنفيذ. والأخيرة هي أخطاء غير فادحة ولن يتوقف التنفيذ
هنالك نوع آخر من رسائل التقرير بالخطأ في مرحلة البناء والتجميع وهي E_STRICT
. هذه الرسائل تستخدم لإقتراح تغيير في
المصدر لتأكيد انه يقوم بنجاح بالتشغيل البيني و متوافق مع الإصدارات القادمة من PHP
يمكن تغيير طريقة تقرير الأخطاء باستخدام ضبط PHP أو/و عن طريق تنفيذ دوال. باستخدام الدالة المدمجة error_reporting()
يمكنك أن تحدد مستوى تقرير الأخطاء والمدة التي يتم فيها تنفيذ المصدر بارسال واحدة من ثوابت تقرير الأخطاء، بمعنى أنه
يمكنك أن تحدد ما إذا كنت تريد أن تحصل على تقارير أخطاء وتحذيرات من دون ملاحظات فسيكون عليك ان يكون الضبط كالآتي:
يمكنك أيضاً التحكم ما إن تظهر تلك الأخطاء على الشاشة أم لا (مفيدة في مرحلة التطوير)، وهل يتم تقييدها أم لا (مفيدة في العمل النهائي). للمزيد من المعلومات قم بزيارة تقرير الأخطاء.
يمكنك إخبار PHP لكي يقوم بكبح أخطاء معينة باستخدام رمز التحكم بالأخطاء @
. كل ما عليك أن تضع هذه العلامة في بداية
الجملة البرمجية، سينتج من هذا أن أي خطأ ينجم من تلك الجملة فسيتم كبحه.
سيقوم هذا بطباعة $foo['bar']
إذا كان موجوداً، ولكن ببساطة يسقوم بإرجاع القيمة الفارغة NULL ولا شيء سيتم طباعته، وذلك
في أي ما ان كان المتغير $foo
أو الفهرس 'bar'
غير موجود. من غير رمز التحكم هذه الجملة قد تنتج أي من هاتين الرسالتين:
PHP Notice: Undefined variable: foo
أو PHP Notice: Undefined index: bar
.
قد تبدو هذه فكرة جيدة ولكن هنالك مفاضلات غير مرغوب فيها. تقوم PHP بالتعامل مع الجمل التي تحتوي على الرمز @
بطريقة أقل
كفاءة من تلك التي لا تحتوي على الرمز @
. التمثيل المسبق هو جذر قيم البرمجة ولكن إذا كان الأداء مهم لتطبيقك/مكتبتك فمن المهم
أن تعلم النقص الذي يسببه الرمز @
في الأداء.
وأيضاً يقوم رمز كبح الخطأ بإبتلاع الخطأ تماماً. لن يظهر الخطأ ولن يتم تسجيله. في أنظمة PHP على بيئة العمل النهائية لا تستطيع أن تتحكم بتعطيل وظيفة هذا الرمز. قد ترى بعض الأحيان أنه قد يكون خطأ ما غير مؤذٍ أو غير مهم على الإطلاق ولا يؤثر في شيء فتفضل أن يتم كبح تقريره وعرضه.
كلما ابتعدت عن إستخدام كبح الأخطاء كلما كان أفضل. فمثلاً المثال أعلاه يمكن إعادة كتابته كالاتي بطريقة صحيحة:
هنالك حالة قد يكون كبح الأخطاء فيها شيء منطقي، كاستخدام الدالة fopen()
عندما تفشل في فتح الملف المطلوب. يتوجب عليك فحص
وجود الملف أولاً قبل القيام بفتح، ولكن ماذا إذا تم حذف الملف بعد نجاح عملية وقبل أن تنفذ fopen()
(ربما تكون مستحيلة، ولكن
قد تحدث) عندها ستقوم الدالة بإرجاع القيمة false و رمي خطأ. في الحقيقة هذا شيء يتوجب على PHP أن تقوم بحله ولكن هذه الحالة
قد تكون الوحيدة الصالحة لإستخدام كبح الأخطاء.
كما ذكرنا سابقاً انه لا يوجد طريقة لنظام PHP أن يقوم بمنع رمز الكبح ولكن Xdebug بها ضبط xdebug.scream
ini وستقوم بتعطيل
رمز الكبح. يمكن تفعيل هذا الخيار عن طريق ملف ضبط PHP php.ini
بالأتي:
يمكن أيضاً إسناد القيمة وتفعيل الضبط أثناء التشغيل باستخدام دالة ini_set
.
لاحقة PHP “Scream” توفر وظيفة مشابهة لما توفره Xdebug ولكن ضبط الأولى يسمى scream.enabled
هذا مفيد خاصةً عندما تقوم بفحص المصدر وتتوقع أن هنالك أخطاء قد تكون كبحت. قم باستخدام Scream بحرص وكأداة فحص مؤقتة. هنالك الكثير من مكتبات PHP التي لن تعمل برمز كبح الأخطاء.
يمكن لPHP أن تكون لغة معتمدة على الإستثناءات وتحتاج للقليل من الأسطر لكي تتم عملية التحويل. فعلياً يمكنك رمي أخطاء على شكل
إستثناءات باستخدام كلاس ErrorException
فهو يقوم بإستمداد كلاس Exception
.
هذه ممارسة متعارف عليها يتم تطبيقها من قبل الكثير من أطر العمل الحديثة مثل Symfony و Laravel. في كل من طور التطوير أو طور كشف الأخطاء. كلا الإطارين يقومان بعرض مسلسل مكدس التنفيذ. هنالك عدة حزم متوافرة لإظهار وإدارة الأخطاء بشكل أفضل مثل حزمة Whoops! فهي تأتي بشكل افتراضي مع إطار عمل Laravel ، ويمكن استخدامها أيضا مع أي اطار عمل اخر.
باستخدام رمي الأخطاء على شكل إستثناءات في عملية التطوير يمكنك التعامل بشكل أفضل من النتائج التقليدية، وإذا رأيت إستثناء في عملية التطوير يمكنك تغطيتها في جملة catch مع تعليمات تفصيلية لكيفية التعامل مع هذه الحالة. كل إستثناء تقوم بإمساكه يجعل من برنامجك أكثر ثباتاً وفعالية.
للمزيد من المعلومات والتفاصيل وكيفية استخدام ErrorException
مع طريقة التعامل مع الأخطاء
ErrorException Class.
الإستثناءات هي جزء أساسي من أغلب لغات البرمجة، ولكن يتم التغاضي عنها من قبل مبرمجي PHP. لغات مثل Ruby معتمدة بكثافة على الإستثناءات، لذلك كلما حدث شيء ما خاطئ كطلب HTTP غير ناجح أو استعلام على قاعدة بيانات لم يتم بالشكل الصحيح، أو حتى صورة لم يتم ايجادها، تقوم Ruby (أو gem المستخدم) برمي إستثناء على الشاشة مما يعني أنه هنالك خطأ ما.
لغة PHP نفسها تفتقر لهذا، وعند تنفيذ file_get_contents()
تستخدم إرجاع FALSE
و تحذير.
العديد من أطر عمل PHP القديمة مثل CodeIgniter سيقوم بإرجاع القيمة false وتدوين رسالة في سجل المتابعة وربما تتيح لك استخدام
دالة مثل $this->upload->get_error()
لكي تعرف ماذا حدث. تكمن المشكلة هنا أنه يتوجب عليك الذهاب الى مستندات التوثيق ومعرفة
ما هي دالة إظهار الخطأ لهذا الكلاس، بدلا من جعلها ظاهرة بشكل أوضح.
مشكلة اخرى هي عندما يقوم كلاس برمي خطأ على الشاشة وإيقاف التنفيذ بشكل تلقائي. عندما تقوم بهذا فأنت تقوم بمنع المطور الآخر أن يقوم بالتعامل مع هذا الخطأ بشكل حيوي تلقائي. الإستثناءت يجب ان ترمى لكي تجعل المطور على دراية بحدوث الخطأ، ثم بعدها يكون لديه الحرية في طريقة التعامل معه. مثال:
الكلاس العام Exception
يتيح القليل من السياقات للتحقق للمبرمج. ولكن لعلاج هذا يمكن إنشاء Exception
مخصصة من الكلاس
الأصلي:
هذا يعني أنه يمكن إضافة عدة قطع للإمساك بالإستثناءات catch blocks للتعامل مع عدة إستثناءات بشكل مستقل. هذا يؤدي إلى إنشاء الكثير من الإستثناءات الفرعية، يمكن الإبتعاد عن بعضها باستخدام إستثناءات SPL متوفرة في SPL extension.
فمثلا عندما تستخدم الدالة السحرية __call()
وتم طلب دالة غير صالحة فبدلاً من رمي إستثناء عادي أو إنشاء استثناء خاص بك يمكنك رمي:
throw new BadMethodCallException;
.
هنالك العديد من الأناس السيئين متعدين لإستغلال تطبيقك. من المهم أن تتخذ التحوطات اللازمة لزيادة حماية التطبيق. لحسن الحظ الأناس الجيدين في المشروع المفتوح لحماية تطبيقات الويب The Open Web Application Security Project OWASP قاموا بتجميع قائمة شاملة لكل مشاكل الحماية، وطرق الحماية منها. الإطلاع على هذا المشروع هو مطلب لاي مطور مدرك لأهمية الحماية. الديل Survive The Deep End: PHP Security كتبت بواسطة باراديك برادي، وهو أحد الأدلة الجيدة لحماية تطبيقات PHP.
دائماً ما يتم بناء تطبيقات PHP تعتمد على تسجيل دخول مستخدمين. فإسم المستخدم وكلمة المرور يتم حفظهما في قاعدة البيانات حتى يتم استخدامهما للتحقق من هوية المستخدم عن تسجيل الدخول.
من المهم أن تقوم بتشفير كلمات السر قبل حفظها. تشفير كلمة المرور هو عملية تشفير أحادية الاتجاه لا يمكن استرجاعها وتنفذ على كلمة مرور المستخدم. يتم انشاء نص محدد المدى لا يمكن فكه. هذا يعني نه ستقوم بمقارنة المحتوى المشفر بمثله للتأكد من أنهما متطابقين، فسوف يكونا كذلك إذا كانا من نفس المصدر، ولكن لا يمكن معرفة المحتوى الأصلي. إذا لم يتم تشفير كلمات المرور وتم الوصول غير المصرح به لقاعدة البيانات، فسيكون كل حسابات المستخدمين قد تم السيطرة عليها. يجب تشفير كلمات المرور بشكل مستقل عن طريق إضافة نص عشوائي ملح لكل كلمة مرور قبل تشفيرها. فذلك يساعد على تجنب هجمات القوامين التي تقوم باستخدام جداول قوس المطر “Rainbow tables” (وهي قائمة عكسية معدة مسبقاً من مجموعة تشفيرات لشفرات كلمات مرور كثيرة الاستخدام). التشفير والتمليح مهم جدا حيث انه بعض المستخدمين يقوم باستخدام نفس كلمة المرور في عدة أجهزة أو خدمات أخرى وقد تكون جودة كلمات مرورهم غير قوية كفاية. لحسن الحظ، PHP قد سهلت هذه المهمة!
تشفير كلمات المرور باستخدام password_hash
في إصدارة PHP 5.5 تم إضافة دالة password_hash()
. حالياً تستخدم هذه الدالة لوغاريثمية BCrypt، وهي اللوغاريثمية الأقوى حتى
الآن في PHP. ستيم مستقبلاً إضافة الدعم لعدة لوغاريثمات أخرى حسب الحاجة. تم إنشاء مكتبة password_compat
لإتاحة توافقية
لإصدارات PHP المتقدمة PHP >= 5.3.7.
أدناه سنقوم بتشفير نص، ثم نقوم بمقارنته بنص آخر. بما أن كلا النصين مختلفين، (كلمة مرور صحيحة مقارنة بـ كلمة مرور خاطئة) ستفشل عملية تسجيل الدخول.
password_hash()
takes care of password salting for you. The salt is stored, along with the algorithm and “cost”, as part of the hash. password_verify()
extracts this to determine how to check the password, so you don’t need a separate database field to store your salts.
لا تقم (أبداً) بالوثوق بأي مدخلات إلى التطبيق أو المصدر. دائماً قم بتعقيم ومراجعة هذه المدخلات قبل استخدامها في المصدر.
الدالتان filter_var()
و filter_input()
يمكنهما تعقيم ومراجعة صيغ النصوص ( كيغة البريد الإلكتروني مثلاً).
المدخلات الأجنبية يمكن أن تكون أي شيء: $_GET
و $_POST
كمدخلات النماذج، بعض القيم من المتغيرات العامة $_SERVER
،
وأي محتوى طلب HTTP باستخدام fopen('php://input', 'r')
. تذكر بأن المدخلات الأجنبية ليست محصورة على المدخلات من النماذج
المرسلة من المستخدم. الملفات المرفوعة والمحملة وقيم المتغيرات وبيانات الكوكيز وبيانات تطبيقات وخدمات الويب
هي مدخلات أجنبية أيضاً.
طالما يحتمل أن يتم حفظ البيانات والوصول إليها لاحقاً، فهي ما تزال مدخلات أجنبية. في كل مرة تقوم بمعالجة أو دمج أو أدراج بيانات في المصدر، تسأل ما إذا كانت البيانات تم تصفيها بطريقة صحيحة ويمكن الوثوق بها.
بشكل عام البيانات تصفى بشكل مختلف بناءً على كيفيتها. مثلا، عند تمرير مدخلات أجنبية إلى مخرجات صفحة HTML عندها سيتم
تنفيذ HTML و JavaScript في الموقع! هذا ما يسمى Cross-Site Scripting (XSS) ويمكن أن يكون هجوماً خطيراً جداً.
طريقة لتفادي هذا الهجوم هو عن طريق تعقيم كل البيانات التي ستعرض للمسخدم قبل عرضها في الصفحة عن طريق حذف كل وسوم HTML
باستخدام الدالة strip_tags()
أو إسقاط الرموز والوسوم باستخدام دوال ذات معنى خاص بعناصر HTML htmlentities()
أو
htmlspecialchars()
.
مثال آخر، تمرير قيم لكي يتم تنفيذها على شكل أمر. فهذا يعتبر من أخطر المهددات (وهي فكرة سيئة)، ولكن يمكن استخدام
الدالة escapeshellarg()
لتعقيم وتنفيذ قيم الأمر.
مثال أخير وهو قبوم مدخلات أجنبية لتحديد ملف ما لعرضه من الملفات. قد تكون هذه ثغرة عن طريق تغيير اسم الملف إلى مسار ملف
ما. فستحتاج أن تقوم بإزالة كل من "/"
و "../"
وما يسمى null bytes وأي رموز من مسار الملف حتى لا يتم إدراج
ملفات خاصة أو محمية من العرض أو ملفات حساسة.
filter_var
filter_input
التعقيم هو إزالة أو إسقاط أي رموز غير آمنة أو غير مصرح بها من المدخلات الأجنبية.
مثلاً يجب أن تقوم بتعقيم المدخلات الأجنبية قبل إدراج المدخل في HTML أو قبل إدراجها في إستعلام SQL مباشرة. عندما تستخدم ربط القيم باستخدام PDO فستقوم PDO بتعقيم المدخلات تلقائياً.
بعض الأحيان قد تسمح ببعض وسوم HTML الآمن كمدخلات لتتضمن في محتوى صفحة HTML. تطبيق هذا صعب للغاية والبعض يقومون بتجنبه باستخدام صيغة أكثر إحكاماً مثل Markdown أو BBCode بالرغم بأن هنالك مكتبات مخصصة لهذا السبب HTML Purifier.
من الخطير تنفيذ عملية unserialize()
من بيانات مدخلة من المستخدم أو من مصادر غير موثوقة. القيام بذلك يسمح للمستخدم أن يقوم بإنشاء
كائنات (بمحتوى مسبق التعريف) فسيتم تنفيذها من قبل destructor حتى ولو لم يتم استخدام هذه الكائنات. عندها يجب أن لا يتم عمل
unserialize لأي بيانات غير موثوقة.
إذا كان لابد أن تقوم بعمل unserialize لبيانات من مصادر غير موثوقة، عندها قم باستخدام خيار allowed_classes
لتحديد أي نوع من الكائنات يمكن أن يتم عمل unserialize عليه. متوفر في إصدارة PHP7 فقط
يتم التحقق من البيانات الأجنبية المدخلة كما تتوقع منها أن تكون. مثلا قد تريد ان تتحقق من بريد إلكتروني و رقم هاتف وعمر عندما تقوم بمعالجة طلب تسجيل.
عندما تقوم بإنشاء ملف ضبط لتطبيقك، فهنالك أفضل الممارسات التي ينصح بتطبيق إحداها:
.php
. وهذا يضمن أنه حتى وإن تم الوصول
للملف مباشرة، فلن يتم طباعة أي نص.وهو خيار ضبط في إعدادات PHP
**ملاحظة: منذ الإصدارة PHP 5.4.0 تم إزالة خيار ضبط register_globals
تمام. وتم إدراج هذا الفصل بمثابة تحذير لكل من
ينوي الترقية لتطبيق متوافق مع إصدار قديم.
عندما يتم تفعيل register_globals
، فسيقوم بإنشاء عدد من المتغيرات من متغيرات عامة من:
$_POST
و $_GET
و $_REQUEST
وجعلها متوفرة في النطاق العام لتطبيقك. ويتسبب بسهولة إلى مشاكل في الحماية فلا يتمكن
تطبيقك من التأكد من مصدر البيانات ومن أين تأتي.
مثلاً: $_GET['foo']
سيكون متوفراً بالإسم $foo
مما يتسبب في الكتابة على المتغيرات التي لم يتم تعريفها.
فإذا كنت تستخدم إصدارة أقل من PHP 5.4.0 قم بالتأكد من أن الخيار register_globals
غير مفعل.
يفيد تدوين الأخطاء في إيجاد المشكل في تطبيقك، ولكن يمكن أن تعرض معلومات حساسة عن هيكلة التطبيق للعالم الخارجي. لحماية تطبيقك بكفاءة عالية من المشاكل التي قد تحدث من مخرجات هذه الرسائل يجب أن يتم ضبط المخدم بطريقة مختلفة في بيئة العمل النهائية عما هو عليه في بيئة التطوير.
لإظهار أي خطأ يحدث أثناء التطوير، قم بضبط الخيارات في php.ini
كالاتي:
إسناد القيمة
-1
يقوم بتفعيل ظهور أي خطأ محتمل وأي مستويات يتم إضافتها في المستقبل على إصدارات PHP مستقبلية. الثابتE_ALL
سيقوم أيضاً بنفس الشيء ابتداءً من إسدارة PHP 5.4 php.net
مستوى تقرير الخطأ في الثابت E_STRICT
قد تم إدراجه في الإصدارة 5.3.0 وهو خيار منفصل من المستوى E_ALL
ولكن صار
جزءً من E_ALL
في الإصدار 5.4.0. ما معنى هذا؟
هذا يعني أنه إذا كنت تريد تقرير كل الأخطاء في الإصدار 5.3 سيتوجب عليك أن تستخدم -1
أو E_ALL | E_STRICT
.
تقرير كل الأخطاء المحتملة بناء على إصدارات PHP
-1
or E_ALL
-1
or E_ALL | E_STRICT
-1
or E_ALL
لإخفاء الأخطاء في بيئة العمل النهائية قم بضبط الخيارات في php.ini
كالآتي:
بخيارات الضبط هذه في بيئة العلم النهائية، سيتم تدوين الأخطاء في سجل الأخطاء في المخدم ولكن لن يظهر أي منها للتمسخدم. للمزيد من المعلومات عن هذه الخيارات، قم بالإطلاع عليها في دليل PHP:
يعتبر كتابة الإختبارات التلقائية لكود PHP هو من أفضل الممارسات التي تؤدي لتطبيقات مبنية بصور صحيحة. الإختبارات التلقائية هي أداة ممتازة للتأكد من أن تطبيقك لن يتوقف عندما تقوم بإدراج أو إضافة خواص وعمليات جديدة ويجب عدم إهمالها!
هنالك أنواع معدودة لإدوات الإختبار (أو أطر عمل) متوفرة للغة PHP، وكل نوع يقوم باستخدام طريقة مختلفة كلها تقوم بتحقيق هدف تفادي القيام بعمليات الإختبار اليدوية وتلبية إحتياج فرق تأكيد الجودة، للتأكد من أن التغييرات الجديدة لم تقم بإيقاف عمل تلك الخواص الموجودة مسبقاً.
مقتبس من ويكيبيديا Test Driven Development بالعربية: بالإنجليزية:
تطوير موجه بالاختبار (بالإنجليزية: Test-driven development (TTD))، هو مصطلح يطلق على إحدى عمليات تطوير البرمجيات التي تعتمد على تكرار دورة تطوير قصيرة جداً: بدايةً، يقوم المبرمج بكتابة حالة فحص أوتوماتيكية فاشلة ويجب على حالة الفحص هذه أن تعرّف تحسينا معينا أو وظيفة جديدة. ومن ثم يقوم بكتابة الشيفرة التي تجعل حالة الفحص ناجحة وأخيرا يقوم بإعادة تصنيع الشيفرة كي تتلاءم مع المعايير.
هنالك بضع أنواع مختلفة من الإختبارات التي يمكن تنفيذها على تطبيقك:
Unit Testing هو طريقة برمجية للتأكد من أن الدوال والكلاسات والعمليات يعملون كما يجب، ابتداءً من نقطة بنائهم وطول فترة وجودهم في دائرة التطوير. وذلك عن طريق إختبار القيم المدخلة والمخرجة من دوال والعمليات لضمان أن المنطق الداخلي يعمل بصورة صحيحة. باستخدام حقن التوابع Dependency Injection وبناء بيانات افتراضية “mock” من كلاسات وصفات، تمكنك من التأكد بأن التوابع مستخدمة بطريقة مثلى في تغطية الإختبار.
عندما تقوم بإنشاء كلاس أو دالة يجب أن تقوم بعمل إختبار وحدة لكل وظيفة يجب أن يقوم بعملها. ابتداءً من انه يجب ان تتأكد من
فشل الإختبار عندما تقوم باستخدام قيم خاطئة قم التأكد من نجاحه عند استخدام قيم صحيحة. فهذا سيساعد بانه عندما تقوم بعمل تغييرات
أو تطويرات على هذه الكلاس أو الدالة لاحقاً في دورة التطوير بإن الوظائف القديمة لن تتوقف وستعمل معاً كما هو متوقع. البديل الوحيد
قد يكون الدالة var_dump()
في ملف test.php حيق لا يمكن بناء أي تطبيق صغير كان أو كبير.
الإستخدام الآخر لوحدات الإختبار هو المشاركة في مشاريع مفتوحة المصدر. إذا كان يمكنك كتابة إختبار يظهر فشل وظيفة معينة، عندها قم بإصلاح هذا الخطأ ثم اظهر نجاح الإختبار، فعندها التعديلات يتم قبولها بسرعة. إذا كان لديك مشروع يقبل طلبات الدمج pull requests عندها يجب اقتراح اختبار الوحداك كمطلب أساسي.
PHPUnit هو إطار عمل إختباري لكتابة الإختبارات لتطبيقات PHP ولكن هنالك بضع بدائل أخرى:
الإختبارات المتكاملة (يطلق عليها التكامل والإختبار بعض الأحيان ويرمز لها بالإختصار “I&T”) وهو في مرحلة إختبار البرنامج بحيث يتم دمج دول البرنامج وإختبارها كمجموعة متكاملة. وتحدث بعد إختبار الوحدات وقبل إختبار التحقق. الإختبارات المتكاملة تأخذ كمعطيات الدوال التي تم تطبيق إختبار وحدة عليها ثم جمعها معاً في تجميعه تتوائم مع خطة تجميع الوظائف سوياً ثم إخراج مخرجات جاهزة لإختبار النظام.
العديد من الأدوات التي تستخدم في اختبار الوحدات يمكن استخدامها في الإختبارات المتكاملة فهما يتشابهان في عديد من المفاهيم الأساسية.
يعرف أيضاً بإختبار القبول، يعتمد الإختبار الوظيفي على استخدام أدوات لإنشاء اختبارات تلقائية تقوم فعلياً باستخدام البرنامج بدلاً من التحقق من كل وحدة على حدة تقوم بالوظيفة الصحيحة، وأن هذه الوحدات تقوم بالتخاطب والعمل سوياً بشكل صحيح. هذه الأدوات تعمل باستخدام بيانات حقيقية وتقوم بمحاكاة مستخدمين حقيقيين للبرنامج.
Behavior Driven Development. هنالك نوعان من هذا النمط: SpecBDD و StoryBDD. SpecBDD: يركز على السلوك التقني للكود. StoryBDD: يركز على الخواص والتفاعلات الفعلية. هنالك إطارا عمل لكلا النوعين.
باستخدام StoryBDD يمكن كتابة قصص مقروءة تقوم بوصف سلوك التطبيق. هذه القسس يمكن ان تقوم بتنفيذ إختبارات حقيقية للتطبيق. إطار العمل المستخدم في تطبيقات PHP للنوع StoryBDD Behat وتم استيحائه من مشروع Cucumber في Ruby.
باستخدام SpecBDD يمكن كتابة مواصفات تصف كيف يجب أن يكون سلوك الكود الفعلي. فبدلاً من إختبار الدالة أو العملية، فأنت تقوم بوصف سلوك الدالة أو العملية. يوجد في PHP إطار عمل PHPSpec لنفس الغرض. هذا الإطار تم استيحائه من مشروع RSpec project في Ruby.
بجانب اطر العمل الإختبارية والسلوكية، هنالك عدد من الأطر العامة والمكتبات المساعدة المفيدة لأي وسيلة مفضلة.
يمكن لتطبيقات PHP ان تنشر وتعمل على سيرفرات عمل نهائية بعدة طرق. PHP applications can be deployed and run on production web servers in a number of ways.
أو المنصة كخدمة وتوفر النظام ومعمارية الشبكة اللازمة لتشغيل تطبيق PHP على الويب. هذا يعني انه لا يوجد ضبط لتشغيل تطبيقات PHP أو أطر عمل PHP.
مؤخراً صار PaaS طريقة مشهورة لنشر واستضافة وتطوير تطبيقات PHP بكل الأحجام. يمكن ايجاد قائمة ببعض هذه المنصات PHP PaaS “Platform as a Service” providers في فصل المصادر resources section.
Virtual or Dedicated Servers إذا كنت مرتاح بالعمل كمشرف نظام أو مهتم بتعلمه فالسيرفرات المخصصة والإفتراضية تتيح لك مطلق الحرية والتحكم في بيئة التطبيق النهائية.
تقترن PHP مع nginx باستخدام البنية المدمجة FastCGI Process Manager (FPM) وهو سيرفر خفيف ذو كفاءة عالية. ويقوم باستخدام ذاكرة أقل من نظيره Apache ويقوم بإدارة عدد أكبر من الطلبات المتزامنة. وهو مناسب في السيرفرات الإفتراضية بحيث لا يوجد الكثير من الذاكرة لإهدارها.
تملك PHP و Apache تاريخاً طويلاً معاً. فـ Apache واسع الإنتشاء ولديه العديد من الوحدات لتمديد وظائفه. فهو خيار مشهور لكل السيرفرات المشتركة وطريقة سهلة لتشغيل إطر عمل PHP وتطبيقات المصدر المفتوح مثل WordPress. للأسف Apache يستخدم الكثير من المصادر بعكس Nginx ولا يقوم بإدراة العديد من الزوار في نفس الزمن.
يوجد عدة طرق لضبط PHP للعمل مع Apache. فالطريقة الأكثر شيوعاً وأسهلها هي تنصيب prefork MPM مع الوحدة mod_php5. بينما هو ليس بخيار جيد في استهلاك الذاكرة ولكنه الأبسط للإستخدام والتشغيل. ويعتبر أفضل خيار إذا كنت لا تنوي التعمق في إدارة السيرفرات. لاحظ أنه عند استخدام mod_php5 فإنه يجب عليك استخدام prefork MPM.
عوضاً عن ذلك، إذا كنت تريد أن تعتصر المزيد من كفاءة الأداء والإستقرار من Apache عندها يمكن الإستفادة من نفس نظام FPM مثل Nginx وتشغيل worker MPM أو event MPM مع الوحدة mod_fastcgi أو mod_fcgid. هذا الضبط سيكون ذا تأثير واضح وكبير على الذاكرة وسرعة ملحوظة ولكن هنالك جهد أكبر للتنصيب.
إذا كنت تستخدم Apache 2.4 أو احدث فيمكنك استخدام mod_proxy_fcgi لكي تزيد من كفاءة الأداء وهو سهل التنصيب والضبط.
إذا وجدت نفسك تقوم بتغيير مخططات قاعدة البيانات يدوياً أو تشغيل الإختبارات يدوياً قبل تحديث الملفات (يدوياً) فعليك التفكير مرة اخرى. في كل مرة تقوم فيها بتحديث تطبيقك إلى نسخة أحدث يدوياً، هنالك فرصة لحدوث خطأ. سواء كنت تتعامل مع وسيلة سهلة للتحديث و أو عملية بناء شاملة أو حتى خطة تكامل مستمرة Continues Integration. عندها البناء التقائي هو صديقك!
من بين المهام التي قد تحتاج أن تكون بصورة تلقائية:
يمكن وصف أدوات النشر بأنها مجموعة من الأوامر الكتابية تقوم بإدارة مهام نشر البرنامج. أدوات التطوير لا تعتبر جزء من البرنامج فهي تمثل البرنامج من الخارج فقط.
هنالك العديد من الأدوات المتوفر ومفتوحة المصدر تساعدك للبناء والنشر التلقائي. بعضها كتب بلغة PHP وبعضها لا. وهذا ليس سبب يدعوك لعدم استخدامها، إذا كانت تناسب ما تقوم به. بعض الأمثلة:
Phing تمكنك من التحكم في عملية تحزيم وإختبار ونشر تطبيقك في إطار استخدام ملف XML. Phing (وهو مبني على Apache Ant) يتيح مجموعة مهام عادة ما تستخدم لتنصيب أو تحديث تطبيقات الويب ويمكن تمديدها للمزيد من المهام. وتكتب بلغة PHP. فهي أداة فعالة وثابتة وموجودة منذ مدة طويلة، ولكن يمكن النظر لهذه الأداة بأنها قديمة بعض الشيء بسبب الطريقة التي تتعامل بها مع ملفات الضبط XML.
Capistrano وهو نظام يخص المطورين المتوسطين - المتقدمين لتنفيذ أوامر في بنائية متكررة واحدة منها أو أكثر في أجهزة عن بعد. تم ضبطه لمشر تطبيقات Ruby on Rails، ولكن يمكن بنجاح نشر تطبيقات وأنظمة PHP باستخدامه. الإستخدام الناجح لـ Capistrano يعتمد على خلفية عمل باستخدام Ruby و Rake. نشر ديف جاردنرز مقالة بعنوان PHP Deployment with Capistrano فهي بداية جيدة لمطوري PHP المهتمين باستخدام Capistrano.
Rocketeer إستمدت فلسفتها من إطار عمل لارافيل Laravel. يهدف لأن يكون سريع وسهل الإستخدام مع إفتراضيات ذكية. يقوم بالعمل على عدة سيرفرات عدة منصات و نشر كلي وجزئي يمكن تنفيذهم على التوازي. كل شيء في هذه الأداة يمكن أن يتم تحويله أو تمديده وكل شيء مكتوب بلغة PHP.
Deployer وهي أداة نشر كتبت بلغة PHP فهي بسيطة وعملية. تقوم بتنفيذ مهام على التوازي والنشر الجزئي مع التنسيق ما بين السيرفرات. وصفات لمهام مكررة لأطر عمل مثل Symfony و Laravel و Zend Framework و Yii. مقالة يونس رفيع Easy Deployment of PHP Applications with Deployer تعتبر درس ممتاز لنشر التطبيقات باستخدام هذه الأداة.
Magallanes وهي أداة أخرى مكتوبة بلغة PHP مع ضبط بسيط في ملفات YAML. تدعم بيئات وسيرفرات متعددة و النشر الجزئية ومدمج معها بعض المهام المضمنة والتي تتيح لك النفوذ مع أدوات وأطر عمل مشهورة.
إدارة وضبط السيرفر هي مهمة شاقة خصوصاً عندما تكون موجهة على عدة سيرفرات. هنالك أدوات تتعامل مع هذا الوضع وأتمتتة البنية التحتية للتأكد من أنه لديك سيرفرات تم ضبطها بطريقة مثلى. عادة ما تتكامل مع استضافات سحابية مثل Amazon Web Service و Heroku و DigitalOcean وغيرها. لإدارة الوحدات التي تقوم بتنسيق التطبيق بشكل أبسط.
Ansible وهي أداة لإدارة البنية التحتية باستخدام ملفات YAML. من السهل البدء بالاستخدام وإدارة وتنسيق تطبيقات كبيرة ومعقدة. هنالك API لإدارة الوحدات السحابية باستخدام بضع أدوات.
Puppet وهي أداة تستخدم ملفات ولغة خاصة بها لإدارة وضبط السيرفرات. يمكن استخدامها في Master/Client وايضا يمكن استخدامها في طور “master-less”. في طور master/client يقوم Client باقتراع الماستر المركزي لطلب ضبط جديد في وحدات زمنية متفرقة لتحديث نفسها إذا لزم الأمر. وفي طور master-less يتم إرسال التحديثات إلى النقاط.
Chef وهو إطار عمل قوي مبني على Ruby يمكن من بناء بيئة السيرفر بالكامل أو صناديق افتراضية وترتبط بشكل جيد باستخدام خدمة في Amazon Web Services تسمى OpsWorks.
الربط المستمر هو ممارة في تطوير البرامج حين يكون هنالك أعضاء فريق يقومون بربط أعمالهم بشكل متواصل، عادة ما يكون كل شخص بالربط على الأقل مرة في اليوم - مما يعني العديد من الربط في خلال اليوم الواحد. العديد من الفرق ترى أن استخدام هذه الممارسة يؤدي إلى خفض فعلي لمشاكل الربط وتتيح للفرق أن تقوم بتطوير برامج متماسكة بسرعة.
– مارتين فولر
هنالك طرق مختلفة لتطبيق الربط المستمر في PHP. يعد Travis CI من أفضلهم فهو يقوم بتحقيق الربط المتواصل بشكل حتى للمشاري الصغيرة. وهو عبارة عن خدمة مستضافة لمجتمع المصدر المفتوح. وترتبط مع GitHub وتوفر دعم من الدرجة الأولى للعديد من اللغات من ضمنها PHP.
تشغيل التطبيق على بيئات مختلفة من تلك التي في بيئة التطوير والعمل النهائي تسبب في ظهور أخطاء غريبة. ومن الصعب إدارة البيئات المختلفة محدثة وتعمل بنفس الإصدارات لكل المكتبات عندما يكون التطوير في فريق.
إذا كنت تقوم بالتطوير على Windows وتقوم بالنشر على Linux أو أي شيء غير ويندوز أو يتم التطوير في فريق يجب عليك استخدام آلات افتراضية. قد يكون غريباً بعض الشء ولكن بجانب الإفتراضية المعروفة للبيئة مثل برامج VMWare و VirtualBox هنالك أدوات إضافية تساعد في إنشاء بيئة إقتراضية بخطوات سهلة وبسيطة.
يساعد Vagrant على بناء صناديق افتراضية فوق ما يعرف بالبيئة الإفتراضية Virtual Environment ويتم ضبط هذه البيئة بناءً على ملف ضبط واحد. هذه الصناديق يمكن تنصيبها بشكل يدوي أو باستخدام أدوات “التموين” مثل Puppet أو Chef. تموين الصناديق هو طريقة فعالة لضمان أن جميع الصناديق تعمل بشكل متساوي وتزيل كل التعقيدات لتنصيب الأوامر. ويمكن أيضاً تدمير الصناديق وإعادة إنشائها بدون أي خطوات يدوية مما يجعل من السهل انشاء نسخ جديدة.
يقوم Vagrant بانشاء مجلدات لكي تقوم بمشاركة الكود مابين الجهاز الحلي والجهاز الإفتراضي مما يعني أنه يمكن إنشاء وتعديل ملفاتك وتنفيذها من الجهاز الحالي من دون الحاجة للدخول للجهاز الإفتراضي.
إذا كنت تريد المساعدة للبدء في استخدام Vagrant هنالك بعض الخدام التي قد تكون مفيدة لك:
Rove: خدمة تتيح لك أن تقوم بتوليد بنائية Vagrant بشكل مسبق بناءً على خيارات ويتم التموين باستخدام Chef.
Puphpet: أداة سهلة تدار باستخدام واجهة رسومية لتنصيب أجهزة إفتراضية لتطوير PHP. تركز فقط على PHP. بجانب أجهزة افتراضية يمكن استخدامها للنشر على خدمات استضافة سحابية أيضاً. ويتم التموين باستخدام Puppet.
Protobox: وهي طبقة فوق Vagrant وهو تطبيق ويب بواجهة استخدام لتنصيب أجهزة افتراضية لتطوير الويب. تستخدم ملف YAML واحد للتحكم بكل شيء يتم تنصيبه داخل الجهاز الإفتراضي.
Phansible: يوفر طريقة سهلة لاستخدام واجهة تساعد في توليد خطط Ansible للمشاريع المبنية بلغة PHP.
Docker هو بديل اخف ثقلاً من استخدام جهاز كامل في بيئة تشغيل افتراضية وذلك لأنه يعتمد على ما يسمى الحاويات “Containers”. الحاوية هي عبارة عن بناء من مجموعة أجزاء تقوم في ابسط صورها بوظيفة واحدة فقط، كأن تقوم بتشغيل خادم ويب. الصورة “Image” وهي الحزمة التي تقوم باستخدامها لبناء حاوية. وDocker لديه مستودع مليء بالصور المبنية مسبقاً.
تطبيقاً على حزمة بيئة التطوير LAMP سيكون هناك ثلاثة حاويات: حاوية الخادم، وحاوية مترجم PHP وحاوية قاعدة البيانات MySQL. كما هو الحال مع Vagrant يمكنك تحديد الملفات المسموحة بالمشاركة لكي تستخدمها الحاوية.
بالإمكان ان تقوم بتوليد حاويات باستخدام سطر الأوامر (انظر المثال ادناه) أو لتسهيل عملية التطوير والصيانة يمكن انشاء ملف docker-compose.yml
مع ملفات مشروعك، وتوصف فيه المتطلبات وكيفية تواصل الحاويات فيما بينها.
يساعد Docker في تطوير عدة مواقع مع الحفاظ على العزلة التامة التي يصعب الحصول عليها بدون انشاء أجهزة افتراضية لكل موقع على حدة، ولكن هذا قد يتعارض مع مصادر الجهاز المتوفر، كالمساحة المتوفرة في القرص الصلب أو الزمن المستهلك في إبقاء كل الأجهزة محدثة. فالكفاءة تتمثل أيضا في انه سهل الاستخدام ويتم حفظ نسخة واحدة من كل صورة، بالإضافة لذلك ان الحاويات تستهلك كمية قليلة من ذاكرة النظام وتقوم بمشاركة لب نظام التشغيل الحالي. إذا يمكن انشاء وتشغيل عدد أكبر من الخوادم في نفس الوقت. وعملية انشاء وتشغيل وإيقاف وتدمير الحاويات يتطلب بضع ثوان فقط، ولا داعي لانتظار زمن اقلاع لنظام تشغيل.
بعد تنصيب dockerعلى الجهاز، يمكن تشغيل خادم ويب باستخدام امر واحد.
الامر التالي سيقوم بتحميل مخدم Apache كامل الوظائف مع اخر نسخة PHP واسناد المسار المحلي /path/to/your/php/files
كالدليل الجذر له، ويمكن استعراض الصفحات بزيارة http://localhost:8080
.
بعد تنفيذ docker run
عندها الحاوية تكون إنشئت وقيد العمل في الخلفية.
إذا كنت تريد إيقاف أو تشغيل الحاوية مرة أخرى يمكن استخدام الإسم المقرون وببساطة تنفيذ
docker stop my-php-webserver
و docker start my-php-webserver
بدون إدراج الأوامر المذكورة أعلاه مرة أخرى.
الأمر أعلاه يوضح كيفية انشاء خادم بصورة سريعة. هنالك الكثير ما يمكن تطبيقه، وهنالك آلاف الصور التي يمكن استخدامها على Docker Hub. قم بإمضاء بعض الوقت في تعلم وفهم المصطلحات وقراءة الدليل Docker User Guide لكي تستفيد بكل ما هو متاح. لا تقم ابدا بتنفيذ أي أوامر قمت بتحميلها او وجدتها في مكان ما بدون التأكد من امانها، الصور غير الرسمية لبعض التطبيقات قد لا تحتوي على اخر الرقع والتحديثات الأمنية، فان كان لديك شك، قم باستخدام فقط المستودعات الرسمية. موقع PHPDocker.io يقوم بتوليد كل الملفات التي تحتاجها للاستخدام في حزمة LAMP/LEMP مضمنة بنسخة PHP من اختيارك مع اللاحقات.
تعتبر PHP سريعة في نفسها، ولكن بعض الإختناقات قد تحدث عندما تقوم بعمل إتصالات خارجية أو إدراج ملفات أو غيرها. لحسن الحظ هنالك عدة إدوات متوفرة لتقوم بتسريع أجزاء محددة في التطبيقات أو تقليل عدد مرات استهلاك تنفيذ هذه المهام في كل مرة.
عندما يتم تنفيذ ملف PHP يجب أن يتم تجميع الملف وتحويله لشيفرة تشغير opcodes (وهي لغة أوامر للمعالج). إذا لم يتغير المصدر البرمجي فإن الشيفرة المصدرية ستظل كما هي، إذاً هذه الخطوة التجميعية ستكون مضيعة لمصدر معالجة.
التخزين المؤقت للشيفرة التشغيلية تمنع تكرار التجميعات عبر حفظ الشيفرة في الذاكرة واستخدامها عند الإستدعاء. فهي فعلياً ستقوم بفحص التوقيع أو زمن التعديل للملف أولاً للتأكد من أي تعديلات قد طرأت عليه.
من الواضح أن تخزين شيفرة التشغيل سيؤثر بشكل ايجابي على سرعة التطبيق. منذ الإصدارة PHP 5.5 هنالك محرك مدمج واحد وهو Zend OPcache. باختلاف توزيعة PHP لديك عادة ما تكون هذه الخاصية مفعلة بشكل افتراضي - ابحث عن opcache.enable في مخرجات الدالة phpinfo()
للتأكد. للإصدارات القديمة هنالك لاحقة PECL يمكن استخدامها.
إقرأ المزيد عن التخزين المؤقت للشيفرة البرمجية opcode caches:
هنالك العديد من الأحيان يكون فيها من المفيد القيام بتخزين كائنات بشكل مؤقت في مصدرك مثل البيانات التي من الصعب الحصول عليها أو إتصالات قاعدة البيانات عندما تكون النتائج من الإستعلامات نادراً ما تتغير. يمكن استخدام التخزين المؤقت للكائنات لمخزن بيانات بعد استرجاعها ثم وضعها مباشرة من المخزن المؤقت للإستعلامات القادمة يمكن الحصول عندها على تطور ملحوظ في الأداء بجانب تقليل الحمل على سيرفرات قاعدة البيانات.
العديد من حلول المخازن المؤقتة المشهورة من النوع bytecode تتيح إمكانية تخزين بيانات أخرى أيضاً مما يعني سبب آخر يجعلك تقوم بالإستفادة منها. يتيح كل من APCuو XCache و WinCache يقوموا بتوفير API لحفظ البيانات من كود PHP لمخازن بياناتهم على الذاكرة.
أشهر أنظمة تخزين الكائنات هما APCu و memcached. APCu هو خيار ممتاز لتخزين الكائنات وتضم واجهة API سهلة الإستخدام لإضافة بياناتك الخاصة إلى الذاكرة وسهل التنصيب والإستخدام. التقييد الوحيدهو أنه مقيد بالسيرفر المنصب عليه. Memcached يتم تنصيبه كخدمة منفصلة ويمكن أن يتم الوصول إليه عبر الشبكة، مما يعني أنه يمكن تخزين الكائنات في مخازن بيانات فائقة السرعة في أماكن مركزية والعديد من الأنظمة تتمكن من الإستخدام منها.
لاحظ أنه عند تشغيل PHP في طور Fast-CGI داخل سيرفر الويب، عندها كل عمليات PHP سيكون لديها المخزن المؤقت الخاص بها، مثلاً بيانات APCu سيتكون منفصلة تماماً ولن يتم مشاركتها مع العمليات الأخرى. في هذه الحالات قد تضطر لإستخدام memcached عوضاً عن الأول. نظراً لانه غير مقترن بأي عملية PHP.
في التواصل الشبكي يحصل APCu على أعلى أداء نظراً للطريقة التي تتيح سرعة الوصول، ولكن بالمقابل memcached قابلة للتطوير بشكل أسرع وأكبر. إذا كنت لا تتوقع انه سيكون لديك عدة سيرفرات تخدم تطبيقك عندها لن تستفيد من خواص memcached، إذاً APCu هو أفضل خيار لتخزين الكائنات.
أمثلة إستخدام منطقية لـ APCu:
لاحظ أنه قبل إصدارة PHP 5.5 تتيح APC كل من مخازن كائنات ومخازن bytecode. APCu هو مشروع لجلب مخازن الكائنات إلى PHP 5.5+ لأنه الآن PHP لديها مخازن bytecode مدمج (OPcache).
يعتبر PHPDoc هو معيار قياسي غير رسمي لتوثيق كود PHP. هنالك العديد من والوسوم المختلفة tags. القائمة الكاملة لهذه الوسوم مع الأمثلة موجودة في الدليل الرسمي PHPDoc manual.
أدناه مثال لكيفية توثيق كلاس بداخله بضع عمليات:
هذا التوثيق للكلاس بأكمله به وسم @author و @link. فوسم @author يستخدم لتوثيق محرر الكود ويمكن تكراره لتوثيق عده محررين. والوسم @link يستخدم لربط موقع يوضح العلاقة ما بين الموقع والكود.
بداخل الكلاس في العملية الأولى بها وسم @param لتوثيق نو واسم ووصف المعطى الممر للعملية. بالإضافة لوسمي @return و @throws لتوثيق نوع الإرجاع وتوضيح أي إستثناءات يمكن رميها.
العملية الثانية والثالثة متماثلتين فلديهما الوسم @param كما في العملية الأولى. الإختلاف المهم ما بين العملية الثانية والثالثة هي وجود/عدم وجودة وسم@return.
@return void
تعدي تنبيهنا بأنه لا يوجد مخرجات، وأيضاً إهمال كتابة @return void
يعطي نفس النتيجة (لا يوجد مرتجعات من العملية).
من الصعب إيجاد أعضاء في مجتمع PHP ذوي خبرة وعلم كبيرين في البداية. يمكن إيجاد قائمة جيدة من أعضاء مجتمع PHP وحساباتهم تويتر في:
للإطلاع على أي نسخة تعمل هذه الخدمات قم بالذهاب الى هنا PHP Versions.
بدلاً من إعادة اختراع العجلة ، العديد من مطوري PHP يستخدمون إطر عمل لبنا تطبيقاتهم. أطر العمل تجرد العديد من المستويات الدنيا ومشاكلها وتعقيداتها وتقوم بتوفير واجهة مفيدة وسهلة الإستخدام لإنجاز المهام المعتادة.
لا يتوجب عليك استخدام إطار عمل لكل مشروع. فبعض الأحيان تكون الطريقة التقليدية للكتابة هي الوسيلة المثلى للعمل، ولكن إذا كنت تريد إطار عمل، عندها هنالك ثلاث أنواع متوفرة:
فأطر العمل الصغير هي عبارة عن ربط لطلبات HTTP إلى متحكمات ودوال وغيرها وعادة ما تكون سهلة وسريعة جداً وبعض الأحيان تكون مع بضع مكتبات للمساعدة في التطوير كمساعدات للإتصال والعمل علىقاعدة البيانات وما شابهها. عادة ما تستخدم لبناء خدمات HTTP عن بعد.
العديد من أطر العمل تضيف عدد من المميزات على قالب أطر العمل الصغير وهذه الأطر هي أطر العمل الكاملة. وعادة ما يكون مدمجاً فيها حزم ORM و مصداقة وتحقق.
أطر عمل المكونات عادة ما تكون تجميعة من مكتبات مخصصة لعمل وظيفة محددة. يمكن استخدام بضع منها سوياً لعمل أطار عمل صغير أو كامل.
كما هو مذكور أعلاه “المكونات” هي هدف معروف لإنشاء ونشر وزرع ومشاركة الكود. العديد من حاويات المكونات موجودة بالفعل اشهرها:
كلاهما حاويات لديها أدوات سطور أوامر تساعدك لتنصيب وتحديث وترقية المكونات وقد تم شرحها في فصل Dependency Management.
هنالك أيضاً مكونات خاصة بأطر عمل ومزودين والتي لا تتيح أي أطار عمل على الإطلاق. هذه المشاريع توفع مصادر اخرى من الحزم المتطابقة مع القليل من الإعتمادية على حزم أخرى أو أطر عمل معينة.
مثلاً يمك استخدام FuelPHP Validation package “حزمة للتحقق” من دون الحاجة لاستخدام أطار عمل FuelPHP.
Illuminate components قريباً سيتم عزله من إطار عمل Laravel. حتى الآن أفضل المكونات المعزولة من إطار عمل Laravel قد تم سردها أعلاه.
يمكن ان تشترك في القوائم البريدية الأسبوعية لتبقى مواكبا بالمكتبات والاخبار والاحداث الجديدة، والتنبيهات العامة، كما هنالك مصادر يتم نشرها بين الحين والأخر:
هنالك العديد من كتب PHP للأسف بات بعضها قديم جداً وغير دقيق. بالتحديد الكتب التي تتحدث عن “PHP 6” فهو إصدار غير موجود ولن يكون موجوداً اصلاً. لأن الإصدار الكبير بعد PHP 5.6 هو “PHP7” partly because of this.
هذا الفصل يهدف إلى أن يكون مصدر للكتب الموصى بها في تطوير PHP بشكل عام. إذا كان لديك كتاب تريد إضافته قم بنشر طلب دمج أو Pull-request، وسيتم مراجعة محتواه.
مجمع PHP هو مجتمع متنوع وكبير، وأعضائها جاهزون ومستعدون لخدمة مبرمجي PHP الجدد. تشجع للإنضمام إلى مجموعة مستخدمي PHP وحضور مؤتمرات PHP لتعلم الكثير عن أفضل الممارسات موجودة. يمكنك التواجد في قناة #phpc في IRC على irc.freenode.com وقم بمتابعة حساب تويتر @phpc. قم بالذهاب إلى هناك وقم بمقابلة مطورين جدد وتعلم مواضيع جديدة، وفوق كل هذا قم تكوين صداقات! مصادر لمجتمعات اخرى تضم مجموعة Google+ PHP Programmer community و StackOverflow.
إذا كنت تعيش في مدينة كبيرة، هنالك العديد من مجموعات PHP حولك. يمكنك ببساطة إيجاد مجموعات محلية PUG في قائمة
usergroup-list at php.net والتي بنيت على على PHP.ug. مصدر بديل قد يكون Meetup.com
أو قم بالبحث عن php user group near me
باستخدام محرك البحث المفضل لديك، مثلا Google. إذا كنت تعيش في
مدينة صغيرة قد لا يكون هنالك مجموعة محلية، فلم لا تقوم ببدء بواحدة!
من الجدير بالذكر مجموعتين عالمية: NomadPHP و PHPWomen. NomadPHP تقوم بتوفير إجتماع مستخدمين أونلاين مرتين شهرياً يقوم بالتحدث فيها بضع مشاهير مجتمع PHP. PHPWomen هي مجموعة غير حصرية تستهدف النساء في عالم PHP. العضوية مفتوحة للجميع ولكل من يدعم المجتمع. وتوفر شبكة من الدعم والإرشاد والتعلم وبشكل عام يروجون لإنشاء بيئة “نسائية” إحترافية.
مجتمع PHP يقوم باستضافة مؤتمرات عالمية ومحلية في العديد من المدن حول العالم. عادة ما يتحدث فيها اعضاء مجتمع PHP المعروفين وهي فرصة ممتازة للتعلم مباشرة من قائدي المنشأة.
ElePHPant وهي جالبة الحظ لكل مشروع PHP مع الفيل في تصميمها. تم تصميمها في الأساس لمشروع PHP في عام 1998 من قبل فاينسنت بونتير وهو الأب لكل فيلة PHP حول العالم بعد عشر سنوات تم تجسيمها كدمية. الآن فيلة PHP موجودة في العديد من مؤتمرات PHP ويمتلكها العديد من مطوري PHP في أجهزتهم لمجرد المرح والإيحاء.