الترحيب

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

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

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

الترجمات

PHP: بالطريقة الصحيحة متوفر بعدة لغات اخرى:

كيفية المساهمة

قم بالمساعدة لجعل هذا الموقع أفضل مصدر لمبرمجي PHP الجدد قم بالمساهمة في تطوير المحتوى العربي على GitHub أو المحتوى الأصلي باللغة الإنجليزية على GitHub.

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

قم بالنشر!

PHP: بالطريقة الصحيحة لديه عدة بانرات صور يمكنك ان تضعها في موقعك. قم بالدعم ودع المطورين الجدد يعرفون المصدر لمعرفة معلومات مفيدة!

صور البانرات

للأعلى

قم بالبدء

قم بإستخدام آخر نسخة مستقرة (7.0)

إذا كنت تريد البدء بالتطوير بلغة PHP، إذاً قم قم بإستخدام آخر نسخة مستقرة من PHP 7.0. PHP 7.0 هي نسخة جديدة، تم إضافة العديد من المميزات المميزات الجديدة مقارنة بالنسخ القديمة 5.× . قد تم إعادة بناء محرك اللغة من جديد، فالآن PHP اصبحت اسرع من سبيقاتها.

في الغالب حتى الآن سوف تجد ان PHP 5.× ما تزال مستخدمة مع العلم ان اخر نسخة من PHP 5.× هي PHP 5.6. وهذا النسخة لا تعتبر خياراً سيءً ولكن يتوجب عليك تجربة التحديث الى آخر نسخة مستقرة في أقرب فرصة. سيتوقف الدعم وضخ التحديثات الأمنية على النسخة PHP 5.6 بعد العام 2018. عملية التحديث هي عملية سهلة للغاية، ولكن ، النسخة الأخير ربما لن تدعم أعمال قد صممت على نسخ سابقة التوافقية مع الإصدارات السابقة. إذا كنت غير متأكد من وجود دالة او ميزة في اي إصدار ، يمكنك التأكد عبر زيارة موقع دليل توثيق PHP php.net.

مخدم ويب مدمج

منذ إصدارة PHP 5.4 بإمكانك تعلم PHP بدون تنصيب اي اضافات أو تخصيصات، مع التمتع بكل خصائص مخدم الويب المعتاد. لتشغيل المخدم قم بتنفيذ هذا الأمر من نافذة الأوامر من مجلد مشروعك الرئيس:

> php -S localhost:8000

التنصيب على نظام تشغيل Mac

عادة ما يحتوي نظام التشغيل 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.0 لم تعد هذه الإصدارات جيدة للإستخدام.

هنالك عدة طرق لتنصيب PHP على نظام تشغيل Mac OS X.

التصيب بواسطة Homebrew

Homebrew هو عبارة عن مدير تطبيقات لنظام تشغيل Mac OS x، يساعدك لتنصيب PHP وملحقاتها بكل سهولة. Homebrew PHP هو المستودع الذي يحتوي كل ما يتعلق بـ PHP لمدير التطبيقات Homebrew، وتمكنك من تنصيب PHP بكل سهولة.

حتى هذه اللحظة يمكنك تنصيب كل من php53، php54، php55، php56 ،php70 باستخدام الأمر brew install، ويمكنك التحويل فيما بينهم بتعديل متغير PATH. أو يمكنك استخدام brew-php-switcher للتحويل التلقائي.

التصيب بواسطة Macports

مشروع MacPorts هو مشروع مفتوح المصدر يهدف لتصميم نظام سهل الإستخدام لتجميع وتنصيب وتحديث البرامج المفتوحة المصدر لكل من برامج سطور الأوامر X11، Aqua على نظام تشغيل Mac OS X.

يدعم MacPorts الملفات بلغة الآلة المبنية مسبقاً (Pre-Compiled Binaries) لكي تغني عن اعادة بناء كل حزمة من متطلبات النظام من ملفات المصدر (tarball files)، فهي توفر لك سهولة لتنصيب الحزم خصوصاً عندما لا يكون نظامك يحتوي على احداها.

حتى هذه اللحظة يمكنك تنصيب كل من php54، php55، php56، php70 باستخدام الأمر port install مثلاً:

sudo port install php56
sudo port install php70

ويمكنك تشغيل الأمر select للتحويل ما بين الإصدارات المتوفرة.

sudo port select --set php php70

التنصيب بواسطة phpbrew

phpbrew هي اداة لتنصيب وإدارة أكثر من إصدارة PHP. فهي أداة مفيدة جداً عندما يكون مشروعين يتطلبان إصدارات مختلفة من PHP وتريد تشغيلهما بدون الحاجة لنظام تشغيل افتراضي.

التنصيب بواسطة Liip’s binary installer

وسيلة اخرى متاحة وهي php-osx.liip.ch فهي توفر وسيلة تنصيب لنسخة واحدة لكل من الإصدارات ابتداء من 5.3 حتى 7.0. تتميز بأنها لا تستبدل ملفات حزمة PHP binaries المدمجة مع نظام Apple، ولكنها تعمل على التنصيب في مكان اخر (/usr/local/php5).

البناء من المصدر Compile from Source

وسيلة اخرى تمكنك من التحكم بإصدارات PHP وتنصيبها، وذلك عن طريق بنائها بنفسك. في هذه الحالة يجب التأكد من تنصيب اي من Xcode، أو“Command Line Tools for XCode” التابعة لـ Apple ويمكن تحميلها “Command Line Tools for XCode” من قسم Mac للمطورين (Mac Developer Center).

تنصيب حلول متكاملة مجمعة “الكل في واحد”

كل الحلول السابق ذكرها تتلخص بأنك تطبق عملية تنصيب PHP بنفسك، وهي لا تشمل تنصيب برامج مثل Apache, Nginx او حتى مخدم SQL. “الكل في واحد” هي حلول متكاملة مثل MAMP و XAMPP فهي تقوم بتنصيب كل تلك البرامج وضبطهم معاً، ولكن بالرغم من سهولة التنصيب ألا ان مثل هذه الحلول تفتقر للمرونة.

التنصيب على نظام تشغيل Windows

يمكنك تحميل الملفات التنفيذية من 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).

البرمجة كائنية التوجه (الشيئية) OOP

تحتوي PHP على خواص البرمجة الكائنية بشكل كامل وذلك يشمل الكائنات (class) والكائنات المجردة (abstract class) والمنافذ (interface) والوراثة (inheritance) والبنائيات (constructor) والاستنساخ (clone) والإستثناء (exception) والمزيد…

البرمجة الوظيفية

تدعم PHP دوال كائنات المستوى الأول، بمعنى انه يمكن لدالة ان تسند الى متغير. كل من دوال المستخدم والدوال المدمجة مع اللغة يمكن احالتها باستخدام متغيرات ومناداتها بصورة حيوية ومجهولة. يمكن تمرير الدوال كقيم الى دوال اخرى (خاصية تسمى higher-order Functions) والدوال نفسها بإمكانها إرجاع دوال اخرى!

الإستدعاء (recursion) الذاتي، وهي خاصية تتيح للدالة ان تنادي نفسها، وهي مدعومة من قبل اللغة ولكن معظم البرمجيات تعتمد على التكرارات.

الدوال المجهولة أو اللا إسمية (anonymous functions) خاصية موجودة منذ الإصدارة PHP 5.3 (2009).

أضافت PHP 5.4 إمكانية اسناد دوال وكائنات مغلقة او لا اسمية لنطاق الكائن وقد تم التطوير للإستدعاءات حتى يمكن استخدامها مع كل الدوال في اي حال.

البرمجة التحويلية

تدعم PHP ايضاً عدة اشكال من اشكال البرمجة التحويلية Meta programming عبر عدة وسائل مثل واجهة برمجة تطبيقات الإنعكاس (reflection API) والدوال السحرية (Magic Methods). هنالك عدة دوال سحري مثل __get()، __set()، __clone()، __toString()، __invoke() وغيرها والتي تتيح للمطور ان يربطها بتصرفات الكائنات. يقول مطوري لغة Ruby ان لغة PHP تفتقر الى الدالة method_missing، ولكنها موجودة وتتمثل في كل من __call() و __callStatic().

فضاءات الأسماء Namespaces

كما قد سبق ذكره ان مجتمع 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 القياسية

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

واجهة سطور الأوامر

صممت PHP لكتابة تطبيقات الويب، ولكن من المفيد ايضاً التعامل مع برامج واجهة سطور الأوامر (CLI). برامج PHP المبنية للعمل على سطور الأوامر تساعد على أداء مهام معتادة مثل تجربة ونشر وادارة البرامج بصورة تلقائية.

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

جرب تشغيل أمر PHP هذا من واجهة سطور الأوامر:

> php -i

يدل خيار -i على طباعة بيانات ضبط PHP كما تنفذه دالة phpinfo() تماماً.

ايضاً خيار -a يوفر اوامر تفاعلية مماثلة لشبيهاتها عند ruby IRB و python interactive shell. هنالك عدد من الأوامر والخيارات المفيدة التي يمكنك الاطلاع عليها ايضاً command line options.

لنقم بتجربة كتابة برنامج ترحيبي بسيط بطريقة واجهة سطور الأوامر، قم بإنشاء ملف بإسم hello.php ثم قم بكتابة الاتي:

<?php
if ($argc !== 2) {
    echo "Usage: php hello.php [name].\n";
    exit(1);
}
$name = $argv[1];
echo "Hello, $name\n";

تقوم PHP بعمل متغيران خاصان بناء على القيم التي يعمل بها تطبيقك. $argc وهو متغير رقمي يحتوي على عدد القيم. $argv وهو متغير به مصفوفة تحوتي على قيمة كل من القيم. دائما ما يكون الخيار الأول من القيم هو اسم ملف PHP المراد تنفيذه وفي هذه الحالة هو الملف hello.php. تستخدم دالة exit() بدون قيمة صفرية لاعلام منفذ الأوامر بأن الأمر قد فشل!. يمكن الإطلاع على شفرات الخروج من هنا.

لتنفيذ الملف، قم بفتح نافذة تنفيذ سطور الأوامر ثم قم بكتابة الآتي:

> php hello.php
Usage: php hello.php [name]
> php hello.php world
Hello, world

المصحح Xdebug

واحد من أهم ادوات التطوير، هو مصحح فعال!. فهو يتيح لك تعقب تنفيذ المصدر البرمجي ومراقبة محتواه وتدفق عمليته. Xdebug هو مصحح PHP، يتيح لعدد من من بيئة التطوير المتكاملة (IDE) توفير نقاط توقف وتعقب التدفق لتنفيذ. ايضاً يتيح لأدوات مثل PHPUnit و KCacheGrind عمل تغطية شاملة على المصدر البرمجي لفحصه وتحليله.

اذا كنت تلجأ لاستخدام اي من var_dump()/print_r()، ولم تفي بالغرض؟ اذا عليك ان تستخدم مصحح حينها!

تنصيب Xdebug قد يكون معقد بعض الشيء، ولكن واحدة من اهم مميزاته هو التصحيح عن بعد (Remote Debugging) اذا كنت تقوم بتطوير برنامجك في بيئة محلية ثم تقوم بتجربته داخل نظام افتراضي او في مخدم اخر عندها التصحيح عن بعد هو الخيار الذي يسهل عليك المتابعة والتصحيح بالطريقة الصحيحة.

يمكنك تحديق Apache VHost او ملف .htaccess بالقيم الآتية:

php_value xdebug.remote_host 192.168.?.?
php_value xdebug.remote_port 9000

كل من “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 تملك طريقة مثلى لإدارة تلك التوابع، حتى واذا قمت بإدارتها بشكل يدوي مازلت تحتاج ان تعير انتباهاً لإدراجهم تلقائياً. ولكن لم تعد هذه مشكلة.

حتى الآن هنالك طريقتين مشهورين لنظم إدارة التوابع في PHP ألا وهما Composer و PEAR. Composer حالياً هو الإكثر شهرة لفترة طويلة من الزمن كان PEAR هو النظام الأساسي لإدارة التوابع في PHP. من الجيد معرفة تفاصيل تاريخ PEAR لأنه يمكن ايجاد مصادر فيها حتى ولو لم تستخدمها..

Composer و Packagist

يعتبر Composer أداة ممتازة لأدارة توابع PHP. كل ما عليك هو ان تضع قائمة بالتوابع في ملف composer.json وببضع أوامر بسيطة سوف يقوم Composer بإنزال كل توابع مشروعك بالإضافة لتنصيب وضبط ملف إدراج تلقائي autoload. يعتبر Composer مماثل لـ NPM المستخدم في node.js، أو Bundler المستخدم في Ruby.

يوجد هنالك الكثير من مكتبات PHP متوافقة مع Composer وجاهزة لكي تستخدمها مع مشروعك. هذه المكتبات أو “الحزم” مدرجة في Packagist، المستودع الحصري لكل مكتبات PHP المتوافقة مع Composer.

كيفية تنصيب Composer

الطريقة الآمنة لتحميل composer هي عن طريق التعليمات الرسمية. منها سيتم التحقق من ملفات التنصيب بأنها سليمة ولم يتم التلاعب بها. يقوم التنصيب بتنصيب Composer محلياً في مجلد العمل الحالي.

ننصح بتنصيبه للإتاحة العامة مثلا كنسخة واحدة في /usr/local/bin للقيام بهذا قم بتنفيذ:

mv composer.phar /usr/local/bin/composer

ملاحظة: اذا فشل الأمر السابق بسبب صلاحيات قم بتشغيل الأمر mv مرة اخرى بكتابة الأمر sudo قبله.

لتشغيل Composer المنصب محلياً قم باستخدام php composer.phar وعامةً قم باستخدام composer فقط.

التنصيب على نظام تشغيل Windows

لمستخدمي نظام التشغيل Windows، الطريقة الأسهل وهي استخدام ملف تنصيب ComposerSetup، حيث أنه يقوم بتنصيبه للتوفر بشكل عام على النظام ويقوم بضبط متغيرات $PATH حتى تتمكن من فقط استدعاء الأمر composer من شاشة سطور الأوامر من أي مجلد في النظام.

كيفية تنصيب Composer(يدوياً)

تنصيب Composer يدوياً هو عملية متقدمة ولك هنالك العديد من الأسباب تجعل المطور يقوم باستخدام هذه الطريقة بدلاً من الطريقة التلقائية التقليدية. فالطريقة التقليدية التقائية تقوم بفحص إصدارة PHP الحالية لتقوم بالتأكد من الآتي:

بالمقابل الطريقة التقليدية لا تقوم باي من العمليات المذكورة انفاً، يتوجب عليك ان تقوم ببعض او كل العمليات يدوياً، لتنصيب Composer يدويا قم بالآتي:

curl -s https://getcomposer.org/composer.phar -o $HOME/local/bin/composer
chmod +x $HOME/local/bin/composer

المجلد $HOME/local/bin (أو المجلد الذي تختاره) يجب ان يكون مدرج في متغيرات $PATH. فذا يساعد على أن يكون الأمر composer متوافر من أي مكان.

ويجب الأخذ بالإعتبار بانه عند استخدام تلك الطريقة، سوف تتغير طريقة الإستخدام التي قد تجدها في بعض المراجع php composer.phar install ليكتب بدلاً منها الآتي:

composer install

وهذا ينطبق فقط إذا قم بتنصيب Composer بشكل عام في النظام.

كيفية تحديد وإدراج التوابع

يقوم Composer بتتبع وادارة توابع مشروعك عن طريق ملف يسمى composer.json. يمكنك ادارة هذا الملف يدوياً باستخدام اي محرر نصوص، أو استخدام Composer لإنجاز هذه العملية. يقوم الأمر composer require بإضافة تابع الى مشروعك ، فإذا لم يكن ملف composer.json موجوداً سوف يقوم تلقائياً بإنشائه. مثال لإدراج مكتبة Twig كتابع لمشروعك.

composer require twig/twig:~1.8

عوضاً عن ذلك يمكنك تنفيذ الأمر composer init وسوف يقوم بمساعدتك لإنشاء ملف composer.json بالكامل لكي يتناسب مع مشروعك. ويمكنك ايضاً بعد انشاء ملف composer.json ان تخبر Composer ان يقوم بتحميل وتنصيب التوابع في مجلد vendor/. وهذا ينطبق ايضاً على المشاريع والمكتبات التي تقوم بانزالها ويوجد معها الملف composer.json.

composer install

بعدها، قم بإضافة هذا السطر الى ملف برنامجك الأساسي، حتى يتمكن من اعلام PHP لكي يستخدم المدرج التلقائي autoloader التابع لـ Composer لكي يدرج التوابع لمشروعك.

<?php
require 'vendor/autoload.php';

يمكنك الآن استخدام توابع مشروعك وسيتم إدراجهم تلقائياً باستخدام 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

يمكن ل Composer التحكم في التوابع وملفاتها التنفيذية ايضاً. طريقة الإستخدام واضحة جداً، كل ما عليك فعله هو ادراج كلمة global قبل تنفيذ الأمر. مثلا إذا كنت تريد تنصيب الأداة PHPUnit واستخدامها بشكل عام في نظامك قم بتنفيذ هذا الأمر:

composer global require phpunit/phpunit

هذا الأمر سيقوم بإنشاء مجلد في ~/.composer حيث يقوم بوضع كل التوابع العامة هناك. ولكي تقوم بتنفيذ أوامر وعمليات تلك التوابع من أي مكان، ببساطة قم بإدراج مسار المجلد ~/.composer/vendor/bin الى متغير $PATH في النظام لديك.

PEAR

PEAR هو أقدم برنامج لإدارة التوابع في PHP بحيث استمتع به كثير من المطورين. فهو يقوم بنفس وظائف Composer تمام ولكن مع بعض الإختلافات الملحوظة.

يحتاج PEAR ان يكون لكل حزمة أو تبع هيكلة محددة، حيث يتوجب على كاتب الحزمة أو التابع ان يقوم بتجهيزها لكي يتم استخدامها عن طريق PEAR. استخدام مشروع غير مجهز للعمل مع PEAR هو شيء مستحيل.

يقوم PEAR بتنصيب كل التوابع بشكل عام، مما يعني بعد تنصيب اي منهم مرة واحدة يكون متوفر بشكل عام لكل المشاريع على نفس النظام. قد يكون هذا أمر جيد إذا كان عدة مشاريع تعتمد على نفس التوابع بنفس الإصدارات ولكن مشاكل مثل تضارب الإعتمادية على إصدارات مختلفة عبر المشاريع سوف تظهر!

كيفية تنصيب PEAR

يمكنك تنصيب PEAR عن طريق تحميل ملف .phar ثم تشغيله. يحتوي دليل PEAR على تفاصيل التنصيب لكل نظام تشغيل تعليمات التنصيب.

إذا كنت تستخدم Linux، يمكن أن تطلع على مدير الحزم لديك. Debian و Ubuntu لديهما الحزمة عن طريق apt php-pear.

كيفية تنصيب حزمة أو تابع

إذا كانت الحزمة أو التابع مدرج في قائمة حزم PEAR، يمكنك التنصيب باستخدام الإسم الحصري:

pear install foo

إذا كانت الحزمة مستضافة على قناة اخرى، كل ما عليك هو ان تقوم بتنفيذ استكشاف للقناة discover أولا، ثم عند التنصيب. اطلع على دليل استخدام القنوات لمزيد من التفاصيل لهذا الموضوع.

إدارة حزم وتوابع PEAR باستخدام Composer

إذا كنت تستخدم Composer عندها يمكنك تنصيب بعض حزم PEAR ايضاً، يمكن استخدام Composer لإدارة توابع وحزم PEAR. مثال لتنصيب كود مصدري من pear2.php.net:

{
    "repositories": [
        {
            "type": "pear",
            "url": "http://pear2.php.net"
        }
    ],
    "require": {
        "pear-pear2/PEAR2_Text_Markdown": "*",
        "pear-pear2/PEAR2_HTTP_Request": "*"
    }
}

الجزء الأول "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
$request = new pear2\HTTP\Request();

للأعلى

ممارسات برمجية

الأساسيات

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

الوقت والتاريخ

يوجد كائن (أو كلاس class) في PHP يسمى DateTime يساعد على عمليات قراءة وكتابة ومقارنة وحساب الوقت والتاريخ. هنالك العديد من الدوال المتعلقة بعمليات الوقت والتاريخ مضمنة في PHP ولكن DateTime توفرها بواجهة كائنية (أو شيئية Object-Oriented) للعديد من الإستخدامات. يمكن لهذا الكائن من التعامل مع النطاقات الزمنية، ولكن هذا غير مدرج في هذا الشرح التعريفي البسيط..

لكي نبدأ باستخدام DateTime، قم بتحويل صيغة كاملة صحيحة لتاريخ وزمن بصيغة نصية إلى كائن باستخدام الدالة المصنِعة createFromFormat() أو يمكنك البدء بإنشاء كائن جديد باستخدام new DateTime وينتج من تنفيذ هذا الأخير الوقت والزمن الحاليين. يمكن إستخدام الدالة format() تحويل DateTime إلى صيغة نصية مرة أخرى للتمكن من طباعتها مثلا.

<?php
$raw = '22. 11. 1968';
$start = DateTime::createFromFormat('d. m. Y', $raw);

echo 'Start date: ' . $start->format('Y-m-d') . "\n";

يمكن إجراء عمليات حسابية باستخدام DateTime وذلك باستخدام كلاس DateInterval. يحتوي كلاس DateTime على دوال مثل add() و sub() التي تستخدم مخرجات كلاس DateInterval كمعطيات. لاتقم مطلقاً بكتابة دوال للقيام بعملية حساب كم ثانية في اليوم أو حساب الفترة النهارية أو حتى حساب فرق التوقيت الزمن، ولا تقم بإستخدام بدائل اخرى بشكل عام. قم بإستخدام DateInterval عوضاً عن ذلك . للقيام بحساب فرق التاريخ بين تاريخين قم باستخدام الدالة diff() فهي تقوم بإرجاع DateInterval وعندها يمكن عرض وإستخدامه بسهولة.

<?php
// نقوم بإنشاء نسخة من $start ثم نقوم بزيادة شهر و ستة أيام
$end = clone $start;
$end->add(new DateInterval('P1M6D'));

$diff = $end->diff($start);
echo 'الفرق هو: ' . $diff->format('%m شهر, %d يوم (المجموع: %a يوم)') . "\n";
// الفرق هو: 1 شهر, 6 يوم (المجموع: 37 يوم)

يمكن لكائن DateTime ان يستخدم لإجراء عملية مقارنة بالطريقة التقليدية باستخدام

<?php
if ($start < $end) {
    echo "Start هو قبل end!\n";
}

المثال الأخير يقوم بشرح كلاس DatePeriod. يستخدم لعمليات التكرار للأحداث المتكررة. يمكنه أخذ كائني DateTime كمعطيات البداية والنهاية وكئان DateInterval لتحديد الحدث الزمني ليقوم بإرجاع كل الأحداث المتطابقة بين التاريخين!

<?php
// إطبع جميع أيام الخميس بين $start و $end
$periodInterval = DateInterval::createFromDateString('first thursday');
$periodIterator = new DatePeriod($start, $periodInterval, $end, DatePeriod::EXCLUDE_START_DATE);
foreach ($periodIterator as $date) {
    // إطبع التاريخ لكل خميس
    echo $date->format('Y-m-d') . ' ';
}

من لواحق واجهات API المشهورة Carbon. تقوم بتوريث كل شيء من كلاس DateTime فتقوم فقط بتعديل كود قليل، ولكن بخواص أخرى إضافية تضم ميزة التعريب بالإضافة لعمليات إضافة وطرح التاريخ بصيغ مختلفة مما يعني أنه يمكن إختبار التطبيق باستخدام تاريخ من اختيارك.

نماذج التصميم

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

إذا كنت تستخدم إطار عمل Framework عندها سيكون هيكل مشروعك في إطاره. عندها الكثير من القرارات الهيكلية قد تم إتخاذها لك مسبقاً ولكن ما يزال عليك ان تختار النماذج المثلى لتتبعها في المصدر الذي تقوم بكتابته لبناء المشروع في هذا الإطار. إذا كنت لا تستخدم إطار عمل لبناء برنامج عندها يجب عليك ان تجد وتستخدم النماذج المثلى التي تنطبق على نوع وحجم البرنامج الذي تقوم ببنائه.

العمل بترميز UTF-8

هذا الفصل تم كتابته من قبل أليكس كابال في أفضل ممارسات PHP حيث تم إستخدامها كأساس لنصائحنا للمل بترميز UTF-8.

كن منتبهاً، دقيقاً ومهتماً بالتفاصيل. فليس هنالك طريق واحد.

حتى الآن لم تقم PHP بدعم ترميز Unicode في مستوياتها الأساسية. هنالك طرق للتأكد من ان النصوص قد تمت معالجتها بالترميز UTF-8، ولكنها عملية ليست سهلة وتحتاج الكثير من البحث والتنقيب في كل مستويات تطبيق الويب، ابتداءً من HTML الى SQL وحتى PHP. سوف نقوم بإيجاز مبسط لتطبيقات عملية.

UTF-8 على مستوى 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 إذا كان متوفرة، أو تقوم بإستخدام الدوال الإفتراضية إذا لم تكن الأخرى متوفرة.

UTF-8 على مستوى قاعدة البيانات

إذا كان تطبيقك تقوم بالوصول لقاعدة البيانات MySQL عندها هنالك إحتمال أن النصوص تحفظ بترميز غير UTF-8 في قاعدة البيانات حتى ولو اتبعت كل التحذيرات أعلاه!

لكي تكون متأكداً من أن النصوص تنتقل من PHP إلى MySQL بترميز UTF-8 قم بالتأكد من أن جميع الجداول في قاعدة البيانات قد تم ضبط ترميزها لتسخدم الترميز utf8mb4 في كل من الترميز و الترتيب (Character set and Collation)، وأن تقوم باستخدام utf8mb4 في الإتصال باستخدام PDO، قم بالإطلاع على المثال أدناه فهو شديد الأهمية.

ملاحظة: يجب استخدام ترميز utf8mb4 للدعم الكامل للترميز UTF-8 وليس الترميز utf8! أكمل القراءة لمعرفة السبب.

UTF-8 على مستوى المتصفح

قم باستخدام الدالة mb_http_output() للتأكد من أن تطبيقك يقوم بإخراج نصوص بترميز UTF-8 إلى المتصفح.

سيلزم عندها ان تقوم بإخبار المتصفح باستخدام HTTP Response بأن هذه الصفحة يجب ان تعتبر مرمزة باستخدام UTF-8. سابقاً كان يتم إدراج هذا الإجرا عن طريق إدراج charset في وسم <meta> بداخل وسم <head> في الصفحة. هذا الإجراء هو سليم تماماً ولكن إضافة Content-Type كترويسة header هو عملياً أكثر سرعة.

<?php
// قم بإخبار PHP اننا نستخدم ترميز UTF-8 حتى النهاية
mb_internal_encoding('UTF-8');
 
// قم بإخبار PHP اننا سنقوم بإخراج مخرجات بترميز UTF-8 إلى المتصفح
mb_http_output('UTF-8');
 
// نص لتجربة عملية الترميز
$string = 'Êl síla erin lû e-govaned vîn.';
 
// قم بتحويل النص إلى شكل آخر باستخدام دالة البايت المتعدد Multibyte
// نلاحظ انه يمكننا قطع نص من خارج جدول Ascii لأغراض الشرح فقط
$string = mb_substr($string, 0, 15);
 
// نقوم بالإتصال بقاعدة البيانات ثم نقوم بتخزين النص الذي قمنا بتحويله
// قم بالإطلاع على مثال PDP في هذا المستند لمزيد من المعلومات
// قم بملاحظة اننا استخدمنا `charset=utf8mb4` في بيانات اسم مصدر البيانات (Data Source Name) (DSN)
$link = new PDO(
    'mysql:host=your-hostname;dbname=your-db;charset=utf8mb4',
    'your-username',
    'your-password',
    array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_PERSISTENT => false
    )
);
 
// قم بتخزين النص المتحول بترميز UTF-8 في قاعدة البيانات
// هل قاعدة البيانات والجداول تستخدم ترميز وترتيب `utf8mb4` Charset and collation؟
$handle = $link->prepare('insert into ElvishSentences (Id, Body) values (?, ?)');
$handle->bindValue(1, 1, PDO::PARAM_INT);
$handle->bindValue(2, $string);
$handle->execute();
 
// قم باسترجاع النص الذي قمنا بتخزينه حتى يتم إثبات بأنه قد تم تخزينه بطريقة صحيحة
$handle = $link->prepare('select * from ElvishSentences where Id = ?');
$handle->bindValue(1, 1, PDO::PARAM_INT);
$handle->execute();
 
// قم بتخزين النتيجة إلى كائن حتى نتمكن من طباعته لاحقاً في HTML
$result = $handle->fetchAll(\PDO::FETCH_OBJ);

header('Content-Type: text/html; charset=UTF-8');
?>
<!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>UTF-8 صفحة تجريبية</title>
    </head>
    <body>
        <?php
        foreach($result as $row){
            print($row->Body);  // يجب ان يتم طباعة هذا النص المتحول بترميز UTF-8 بصور صحيحة في المتصفح
        }
        ?>
    </body>
</html>

للمزيد من المصادر

للأعلى

حقن التوابع Dependency Injection

مقتبس من ويكيبيديا الإنجليزية Wikipedia:

حقن التوابع هو تصميم نموذجي برمجي يتيح ازالة التوابع المكتوبة صراحةً ثم جعلها متوفرة للتغيير سواء كان في مرحلة التشغيل ام في مرحلة البناء.

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

المفهوم الأساسي

يمكن شرح هذا المفهوم باستخدام مثال سهل ومبسط.

لدينا كلاس Database يعتمد على محول للتخاطب مع قاعدة البيانات. نقوم بانشاء المحول في دالة الإنشاء ثم نقوم بعمل حقن ثابت. هذا يجعل عملية التجربة والإختبار عملية صعبة وتعني ان الكلاس Database مرتبط بشدة مع المحول.

<?php
namespace Database;

class Database
{
    protected $adapter;

    public function __construct()
    {
        $this->adapter = new MySqlAdapter;
    }
}

class MysqlAdapter {}

يمكن إعادة صياغة هذا المصدر لاستخدام حقن التوابع وفك الإرتباط من التوابع

<?php
namespace Database;

class Database
{
    protected $adapter;

    public function __construct(MySqlAdapter $adapter)
    {
        $this->adapter = $adapter;
    }
}

class MysqlAdapter {}

الآن يمكننا ان نعطي كلاس Database توابعه عن طريق انشائها بنفسه. ويمكن أيضاً انشاء دالة تستقبل التابع كقيمة ثم اسنادها مباشرة أو اذا كان المحول $adapter في وصف عام public property عندها يمكن إسناده مباشرةً.

مشكلة معقدة

إذا كنت قرأت عن حقن التوابع سابقاً عندها قد لفت إنتباهك مصطلح “Inversion of Control” إنعكاس التحكم أو “Dependency Inversion Principle” مفهوم عكس تحكم التوابع. هذه المشاكل المعقدة التي يقوم حقن التوابع بحلها.

إنعكاس التحكم

إنعكاس التحكم للنظام بإبقاء التحكم التنظيمي بالكامل بمنئى عن العناصر أو الكائنات. في مصطلح حقن التوابع هذا يعني فك الإرتباط مع التوابع وعكس التحكم بهذه التوابع في مكان آخر في النظام.

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

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

مفهوم عكس التحكم

مفهوم عكس التحكم هو حرف “D” في مجموعة مفاهيم البرمجة الشيئية S.O.L.I.D والذي يوضح أنه يجب “الإعتماد على التجريد، لا على التحجير أو الإنغلاق”. ببساطة هذا يعني انه التوابع يجب ان تكون واجهات او مجردات عوضاً عن التطبيقات الجامدة او المحجرة. عندها يمكننا ببساطة إعادة صياغة وكتابة المفهوم أعلاه:

<?php
namespace Database;

class Database
{
    protected $adapter;

    public function __construct(AdapterInterface $adapter)
    {
        $this->adapter = $adapter;
    }
}

interface AdapterInterface {}

class MysqlAdapter implements AdapterInterface {}

هنالك عدة فوائد يستفيد منها كلاس Database الآن، فهوالآن يعتمد على واجهة بدلاً من كائن جامد.

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

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

الحاويات Containers

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

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

إقرأ المزيد

للأعلى

قواعد البيانات

عادةً ما تقوم باستخدام قاعدة بيانات لبرنامجك لتخزين المعلومات. لديك خيارات محدودة للإتصال والتعامل مع قاعدة البيانات. الطريقة المستحسنة حتى إصدارة PHP 5.1.0 هي إستخدام لاحقات التشغيل المدمجة مثل mysqli و pgsql و mssql… الخ

لاحقات التشغيل المدمجة ممتازة إذا كنت تستخدم قاعدة بيانات واحدة في برنامجك، ولكن مثلاً إذا كنت تستخدم MySQL والقليل من MSSQL أو ربما تريد ان تتصل مع قاعدة بيانات أوراكل، عندها لن تتمكن من استخدام نفس تلك اللواحق. سوف تحتاج لتعلم طريقة API جديدة لكل لاحقة قاعدة بيانات — وهذا شيء مجهد.

لاحقة MySQL

لاحقة mysql هي لاحقة مدمجة في PHP وقد باتت قديمة وتم الإستغناء عنها وإستبدالها بلاحقتين أخرتين:

لم يتوقف التطوير على اللاحقة mysql منذ زمن بعيد فحسب، بل وقد تم إهمالها منذ إصدارة PHP 5.5.0 ثم تم إزالتها حصرياً في أول إصدارة من PHP 7.0

لمعرفة ما إذا كان تطبيق ما يعمل بهذه اللاحقة يمكنك البحث باستخدام محرر النصوص لديك عن دوال مثل mysql_connect() و mysql_query فإذا ظهرت نتائج بحث إيجابية فهذا يعني أن هذه اللاحقة مستخدمة في التطبيق. وهذا عوضاً عن البحث في ملف php.ini للتحقق من وجود اللاحقة.

حتى وإن لم تكن تستخدم إصدارة PHP 7.0 بعد، عدم الإهتمام بالتحديث في أقرب فرصة يزيد صعوبة المهمة عندما تحدث الترقية. أفضل حل هو استبدال إستخدام mysql بأي من mysqli أو PDO في تطبيقاتك كممارسة أساسية في عملية التطوير حتى لا تضطر لتنفيذها على عجالة في وقت لاحق.

إذا كنت تنوي الترقية من mysql إلى mysqli، هنالك موجهات سهلة تقترح عليك بأن تقوم بالبحث عن mysql_* واستبدالها بـ mysqli_*. هذا المقترح مفرط السهولة، ولكنه يفقد العديد من فوائد وخواص تقدمها mysqli مثل ربط القيم، وهي متوفرة أيضاً في PDO.

لاحقة PDO

تعتبر PDO هي مكتبة مجردة للإتصال بقاعدة البيانات — تم بنائها في PHP منذ الإصدارة 5.1.0 — بحيث توفر واجهات إتصال عادية للعديد من قواعد البيانات المختلفة. مثلا يمكن إستخدام نفس الكود المصدري للإتصال والعمل بقاعدة بيانات MySQL أو SQLite:

<?php
// PDO + MySQL
$pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password');
$statement = $pdo->query("SELECT some_field FROM some_table");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['some_field']);

// PDO + SQLite
$pdo = new PDO('sqlite:/path/db/foo.sqlite');
$statement = $pdo->query("SELECT some_field FROM some_table");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['some_field']);

لا تقوم PDO بترجمة أو تحويل الإستعلامات SQL Queries أو مماثلة الخصائص المفقودة، ولكنها بالفعل تتصل بأكثر من نوع من قواعد البيانات بنفس الوجهة البرمجية API.

للأهمية: PDO تتيح بسهولة حقن مدخلات خارجية (كالمفاتح ID مثلا) في إستعلام SQL Query من دون القلق بشأن تهديدات SQL Injection. وهذا ممكن باستخدام جمل PDO وتقييد وربط القيم PDO Statements.

فلنفترض أن في مصدر PHP يستقبل مفتاح رقمي ID وهو عبارة عن قيمة في إستعلام. هذا المفتاح يجب أن يستخدم لإستخراج بيانات مستخدم من قاعدة البيانات. الطريقة التالية هي الطريقة الخاطئة للقيام بهذه العملية:

<?php
$pdo = new PDO('sqlite:/path/db/users.db');
$pdo->query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- خطأ!

هذا مصدر خاطئ تماماً. فهو يقوم بإدخال قيم خام إلى إستعلام SQL. مما يسبب يعرضك للإختراق بسهولة باستخدام أسلوب حقن الإستعلام SQL Injection. تصور أن مخترق قام بإرسال قيمة ID عن طريق تنفيذ عنوان مثل http://domain.com/?id=1%3BDELETE+FROM+users. سوف يقوم بإسناد للمتغير $_GET['id'] القيمة 1;DELETE FROM users مما يتسبب بحذف جميع سجلات المستخدمين! عوضاً عن ذلك يجب ان تقوم (بتعقيم) المفتاح ID المدخل باستخدام جمل التقييد في PDO.

<?php
$pdo = new PDO('sqlite:/path/db/users.db');
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT); // <-- قم بترشيح بياناتك أولاً (أنظر [ترشيح البيانات](#data_filtering))، مهم جداً خصوصاً لعمليتي INSERT و UPDATE..
$stmt->bindParam(':id', $id, PDO::PARAM_INT); // <-- تلقائياً يتم تعقيم القيم باستخدام PDO
$stmt->execute();

وهذا مصدر صحيح. يتم استخدام تقييد القيم في جملة PDO. فبدورها تقوم تلقائياً بعقيم المدخل ID قبل أن تقوم بإدراجه لقاعدة البيانات مما يمنع إحتمال هجمات SQL Injection.

عند كتابة عمليات مثل INSERT أو UPDATE ، يجب (للأهمية القصوى) ان تقوم بترشيح البيانات أولاً ثم بتعقيمها من العناصر الأخرى مثل (حذف أوسم HTML و JavaScript وغيرها..). سيقوم PDO فقط بتعقيم المدخلات لإستخدامها في SQL وليس لكي تستخدمها أنت في تطبيقك.

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

التفاعل مع قواعد البيانات

عندما يبدأ المطورين بتعلم PHP للمرة الأولى، عادة ما يقومون بدمج عمليات قواعد البيانات مع الطرح المنطقي، بكتابة مصدر كهذا:

<ul>
<?php
foreach ($db->query('SELECT * FROM table') as $row) {
    echo "<li>".$row['field1']." - ".$row['field1']."</li>";
}
?>
</ul>

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

هنالك العديد من الحلول - سواء كنت تفضل استخدام البرمجة الشيئية OOP أو البرمجة الوظيفية Functional Programming- ما يزال يتوجب عليك أن تقوم بالفصل.

مثال لطريقة بدائية:

<?php
function getAllFoos($db) {
    return $db->query('SELECT * FROM table');
}

foreach (getAllFoos($db) as $row) {
    echo "<li>".$row['field1']." - ".$row['field1']."</li>"; // خطأ!!
}

هذه بداية جيدة. قم بوضع كل منهما في ملفين مختلفيين عندها تحصل على عملية فصل نظيفة.

قم بإنشاء كلاس عوضاً عن تلك الطريقة عندها سيكون ليدك نموذج “Model”. قم بإنشاء ملف بسيط .php ثم ضع فيه محتوى العرض المنطقي عندها سيكون لديك العرض “View”، ستلاحظ أنه قريب من نموذج MVC - طريقة معتادة في معمارية البرمجة الشيئية لأغلبية أطر العمل frameworks.

foo.php

<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');

// قم بإدراج النموذج Model
include 'models/FooModel.php';

// قم بإنشاء كائن
$fooModel = new FooModel($db);
// إستخرج قائمة من Foos
$fooList = $fooModel->getAllFoos();

// قم بإدراج العرض View
include 'views/foo-list.php';

models/FooModel.php

<?php
class FooModel
{
    protected $db;

    public function __construct(PDO $db)
    {
        $this->db = $db;
    }

    public function getAllFoos() {
        return $this->db->query('SELECT * FROM table');
    }
}

views/foo-list.php

<?php foreach ($fooList as $row): ?>
    <?= $row['field1'] ?> - <?= $row['field1'] ?>
<?php endforeach ?>

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

هنالك مصدر في موقع PHPBridge يسمى إنشاء كلاس بيانات Creating a Data Class يقوم بتغطية جميع المواضيع المشابهة، من الجيد للمطورين بأن يتعودوا على مفهوم التفاعل مع قواعد البيانات.

طبقات التجريد

العديد من أطر العمل Framework لديها طبقات التجريد الخاصة بها مما قد يجعلها أو لا يجعلها تكون فوق طبقة PDO. غالباً ما يتم محاكاة خواص لنظام قاعدة بيانات مفقودة في الأخرى عن طريق ربط الإستغلامات في دوال PHP وتعطيك نفس التجريد لقاعدة البيانات عوضاً عن مجرد إتصال تجريدي كما تفعل PDO. بالطبع سوف تقوم هذه الممارسة القليل من الجهد ولكن اذا كنت تنوي بناء نظام متنقل يمكنه العمل على كل من MySQL و PostgreSQL و SQLite عندها القليل من الجهد يستحق التعب وكتابة بضع السطور البرمجية.

بعض طبقات التجريد تم بنائها باستخدام التوصية PSR-0 أو PSR-4 بأسماء فضاء قياسية حتى تتمكن من تنصيب أي تطبيق تريد مثل:

للأعلى

النمذجة Templating

توفر النمذجة طريقة مناسبة لفصل التحكم المنطقي من العرض المنطقي. تحتوي النماذج على HTML لتطبيقك، وقد تستخدم صيغ أخرى مثل XML. عادة ما تسمى النماذج بالعرض أو “views” فهي تمثل المكون الثاني من النموذج المعماري للبرمجة الشيئية (MVC) model–view–controller.

الفوائد

تكمن الفائدة الأساسية لإستخدام النماذج هي عملية فصل نظيفة تنشئ بين العرض المنطقي وبقية البرنامج. تكون مسؤولية النماذج الوحيدة هي عرض محتوى مهيئ. ولا تحمل أي مسؤولية تنفيذ إستخراج بيانات أو عمل مهام معقدة. مما يؤدي إلى مصدر سهل القراءة ويكون مفيد خاصة في بيئة العمل في فريق عندها يقوم المطورون بكتابة المصدر البرمجي للعمليات التي تنفذ في المخدم server-side (Controller و Models) ويقوم المصممون بالعمل على جانب العميل client-side.

تقوم النماذج أيضا بتطوير تنظيم شكل ومصدر العرض المنطقي. فالنماذج توضع في مجلد العرض “Views” كلٌ محدد بملف واحد. هذا الأسلوب يساعد على وجود مصدر قابل للإستخدام وإعادة الإستخدام بحيث أنه يتم تقسيم مجموعات المصدر الكبيرة إلى قطع صغيرة وقابلة للإستخدام، عادة ما تسمى الأجزاء Partials. مثلاً في الموقع هنالك رأس وذيل كل منهما يمكن أن يعرفا كنماذج يمكن إدراج كل منهما قبل وبعد نموذج أي صفحة.

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

نماذج PHP العادية

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

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

مثال بسيط لنماذج PHP عادية

باستخدام مكتبة Plates.

<?php // user_profile.php ?>

<?php $this->insert('header', ['title' => 'ملف المستخدم']) ?>

<h1>ملف المستخدم</h1>
<p>مرحباً <?=$this->escape($name)?></p>

<?php $this->insert('footer') ?>

مثال بسيط للتوريث في نماذج PHP عادية

باستخدام مكتبة Plates.

<?php // template.php ?>

<html>
<head>
    <title><?=$title?></title>
</head>
<body>

<main>
    <?=$this->section('content')?>
</main>

</body>
</html>
<?php // user_profile.php ?>

<?php $this->layout('template', ['title' => 'ملف المستخدم']) ?>

<h1>ملف المستخدم</h1>
<p>مرحباً <?=$this->escape($name)?></p>

نماذج التجميع Compiled Templates

بالرغم أن PHP تطورت بطبيعتها لتكون لغة برمجة شيئية، ولكنها لم تتطور بكونها لغة نمذجة. نماذج التجميع مثل Twig و Brainy و Smarty* تملأ هذا الفراغ بتوفير صيغ كتابة جديدة تمتلك المواصفات الحقيقة ككونها نماذج. ابتداءً من الترشيح التلقائي حتى التوريث وتبسيط التحكم في الهياكل فنماذج التجميع قد صممت لكي تكون سهلة الكتابة والقراءة وآمنة للإستخدام. نماذج التجميع يمكن أن تنتشر وتستخدم عبر لغات مختلفة Mustache هو مثال جيد لهذا. بما أن هذه النماذج تستوجب عملية التجميع هنالك فرق في الأداء ولكنه فرق بسيط إذا تم إستخدام تخزين مؤقت بطريقة جيدة (caching).

*بالرغم أن Smarty يوفر ترشيح تلقائي ولكنه غير مفعل بشكل إفتراضي.

مثال بسيط لنموذج تجميعي

باستخدام مكتبة Twig.

{% include 'header.html' with {'title': 'ملف المستخدم'} %}

<h1>ملف المستخدم</h1>
<p>مرحباً {{ name }}</p>

{% include 'footer.html' %}

مثال بسيط للتوريث في نموذج تجميعي

باستخدام مكتبة Twig.

// template.html

<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>

<main>
    {% block content %}{% endblock %}
</main>

</body>
</html>
// user_profile.html

{% extends "template.html" %}

{% block title %}ملف المستخدم{% endblock %}
{% block content %}
    <h1>ملف المستخدم</h1>
    <p>مرحباً {{ name }}</p>
{% endblock %}

المزيد من القراءة

مقالات ودروس

مكتبات

للأعلى

الأخطاء والإستثناءات Errors and Exceptions

الأخطاء

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

مثلاً:

$ php -a
php > echo $foo;
Notice: Undefined variable: foo in php shell code on line 1

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

$ python
>>> print foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined

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

شدة الخطأ

لدى PHP عدة مستويات لشدة الخطأ. يوجد ثلاث أنو معروفة من أنواع رسائل الخطأ والملاحظات والتحذيرات. هنالك عدة مستويات مختلفة من الشدة: E_ERROR و E_NOTICE و E_WARNING. الأولى هي الأخطاء الفادحة التي تحدث أثناء التنفيذ وغالباً ما تسبب فشل في تنفيذ المصدر ويتوجب عليك فحص هذا الخطأ حتى تتمكن من إكمال التنفيذ لأن PHP ستقوم بإيقاف التنفيذ. الثانية وهي رسائل نصحية تسبب المصدر في ظهورها ربما تتسبب أو قد لا تتسبب في حدوث خطأ اثناء تنفيذ المصدر، ولكن لن توقف PHP التنفيذ. والأخيرة هي أخطاء غير فادحة ولن يتوقف التنفيذ

هنالك نوع آخر من رسائل التقرير بالخطأ في مرحلة البناء والتجميع وهي E_STRICT. هذه الرسائل تستخدم لإقتراح تغيير في المصدر لتأكيد انه يقوم بنجاح بالتشغيل البيني و متوافق مع الإصدارات القادمة من PHP

تغيير طريقة PHP لتقرير الأخطاء

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

<?php
error_reporting(E_ERROR | E_WARNING);

يمكنك أيضاً التحكم ما إن تظهر تلك الأخطاء على الشاشة أم لا (مفيدة في مرحلة التطوير)، وهل يتم تقييدها أم لا (مفيدة في العمل النهائي). للمزيد من المعلومات قم بزيارة تقرير الأخطاء.

كبح الأخطاء الداخلي

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

<?php
echo @$foo['bar'];

سيقوم هذا بطباعة $foo['bar'] إذا كان موجوداً، ولكن ببساطة يسقوم بإرجاع القيمة الفارغة NULL ولا شيء سيتم طباعته، وذلك في أي ما ان كان المتغير $foo أو الفهرس 'bar' غير موجود. من غير رمز التحكم هذه الجملة قد تنتج أي من هاتين الرسالتين: PHP Notice: Undefined variable: foo أو PHP Notice: Undefined index: bar.

قد تبدو هذه فكرة جيدة ولكن هنالك مفاضلات غير مرغوب فيها. تقوم PHP بالتعامل مع الجمل التي تحتوي على الرمز @ بطريقة أقل كفاءة من تلك التي لا تحتوي على الرمز @. التمثيل المسبق هو جذر قيم البرمجة ولكن إذا كان الأداء مهم لتطبيقك/مكتبتك فمن المهم أن تعلم النقص الذي يسببه الرمز @ في الأداء.

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

كلما ابتعدت عن إستخدام كبح الأخطاء كلما كان أفضل. فمثلاً المثال أعلاه يمكن إعادة كتابته كالاتي بطريقة صحيحة:

<?php
echo isset($foo['bar']) ? $foo['bar'] : '';

هنالك حالة قد يكون كبح الأخطاء فيها شيء منطقي، كاستخدام الدالة fopen() عندما تفشل في فتح الملف المطلوب. يتوجب عليك فحص وجود الملف أولاً قبل القيام بفتح، ولكن ماذا إذا تم حذف الملف بعد نجاح عملية وقبل أن تنفذ fopen() (ربما تكون مستحيلة، ولكن قد تحدث) عندها ستقوم الدالة بإرجاع القيمة false و رمي خطأ. في الحقيقة هذا شيء يتوجب على PHP أن تقوم بحله ولكن هذه الحالة قد تكون الوحيدة الصالحة لإستخدام كبح الأخطاء.

كما ذكرنا سابقاً انه لا يوجد طريقة لنظام PHP أن يقوم بمنع رمز الكبح ولكن Xdebug بها ضبط xdebug.scream ini وستقوم بتعطيل رمز الكبح. يمكن تفعيل هذا الخيار عن طريق ملف ضبط PHP php.ini بالأتي:

xdebug.scream = On

يمكن أيضاً إسناد القيمة وتفعيل الضبط أثناء التشغيل باستخدام دالة ini_set.

<?php
ini_set('xdebug.scream', '1');

لاحقة PHP “Scream” توفر وظيفة مشابهة لما توفره Xdebug ولكن ضبط الأولى يسمى scream.enabled

هذا مفيد خاصةً عندما تقوم بفحص المصدر وتتوقع أن هنالك أخطاء قد تكون كبحت. قم باستخدام Scream بحرص وكأداة فحص مؤقتة. هنالك الكثير من مكتبات PHP التي لن تعمل برمز كبح الأخطاء.

إستثناء الخطأ

يمكن لPHP أن تكون لغة معتمدة على الإستثناءات وتحتاج للقليل من الأسطر لكي تتم عملية التحويل. فعلياً يمكنك رمي أخطاء على شكل إستثناءات باستخدام كلاس ErrorException فهو يقوم بإستمداد كلاس Exception.

هذه ممارسة متعارف عليها يتم تطبيقها من قبل الكثير من أطر العمل الحديثة مثل Symfony و Laravel. بشكل إفتراضي يقوم Laravel بإظهار كل الأخطاء على شكل إستثناءات باستخدام حزمة Whoops! إذا كان الضبط app.debug، وتقوم باخفاءها عندما تكون غير مفعلة.

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

للمزيد من المعلومات والتفاصيل وكيفية استخدام ErrorException مع طريقة التعامل مع الأخطاء ErrorException Class.

الإستثناءات

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

لغة PHP نفسها تفتقر لهذا، وعند تنفيذ file_get_contents() تستخدم إرجاع FALSE و تحذير.

العديد من أطر عمل PHP القديمة مثل CodeIgniter سيقوم بإرجاع القيمة false وتدوين رسالة في سجل المتابعة وربما تتيح لك استخدام دالة مثل $this->upload->get_error() لكي تعرف ماذا حدث. تكمن المشكلة هنا أنه يتوجب عليك الذهاب الى مستندات التوثيق ومعرفة ما هي دالة إظهار الخطأ لهذا الكلاس، بدلا من جعلها ظاهرة بشكل أوضح.

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

<?php
$email = new Fuel\Email;
$email->subject('العنوان');
$email->body('كيف حالك؟');
$email->to('guy@example.com', 'فلان الفلاني');

try
{
    $email->send();
}
catch(Fuel\Email\ValidationFailedException $e)
{
    // فشل في التحقق
}
catch(Fuel\Email\SendingFailedException $e)
{
    // فشل في إرسال البريد الإلكتروني
}
finally
{
    // يتم تنفيذه بغض النظر عن ما إذا تم رمي استثناء ، وقبل ان يواصل التنفيذ
}

إستثناءات SPL

الكلاس العام Exception يتيح القليل من السياقات للتحقق للمبرمج. ولكن لعلاج هذا يمكن إنشاء Exception مخصصة من الكلاس الأصلي:

<?php
class ValidationException extends 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 تعتمد على تسجيل دخول مستخدمين. فإسم المستخدم وكلمة المرور يتم حفظهما في قاعدة البيانات حتى يتم استخدامهما للتحقق من هوية المستخدم عن تسجيل الدخول.

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

تشفير كلمات المرور باستخدام password_hash

في إصدارة PHP 5.5 تم إضافة دالة password_hash(). حالياً تستخدم هذه الدالة لوغاريثمية BCrypt، وهي اللوغاريثمية الأقوى حتى الآن في PHP. ستيم مستقبلاً إضافة الدعم لعدة لوغاريثمات أخرى حسب الحاجة. تم إنشاء مكتبة password_compat لإتاحة توافقية لإصدارات PHP المتقدمة PHP >= 5.3.7.

أدناه سنقوم بتشفير نص، ثم نقوم بمقارنته بنص آخر. بما أن كلا النصين مختلفين، (كلمة مرور صحيحة مقارنة بـ كلمة مرور خاطئة) ستفشل عملية تسجيل الدخول.

<?php
require 'password.php';

$passwordHash = password_hash('secret-password', PASSWORD_DEFAULT);

if (password_verify('bad-password', $passwordHash)) {
    // Correct Password
} else {
    // Wrong password
}

تصفية البيانات

لا تقم (أبداً) بالوثوق بأي مدخلات إلى التطبيق أو المصدر. دائماً قم بتعقيم ومراجعة هذه المدخلات قبل استخدامها في المصدر. الدالتان 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 وأي رموز من مسار الملف حتى لا يتم إدراج ملفات خاصة أو محمية من العرض أو ملفات حساسة.

التعقيم

التعقيم هو إزالة أو إسقاط أي رموز غير آمنة أو غير مصرح بها من المدخلات الأجنبية.

مثلاً يجب أن تقوم بتعقيم المدخلات الأجنبية قبل إدراج المدخل في HTML أو قبل إدراجها في إستعلام SQL مباشرة. عندما تستخدم ربط القيم باستخدام PDO فستقوم PDO بتعقيم المدخلات تلقائياً.

بعض الأحيان قد تسمح ببعض وسوم HTML الآمن كمدخلات لتتضمن في محتوى صفحة HTML. تطبيق هذا صعب للغاية والبعض يقومون بتجنبه باستخدام صيغة أكثر إحكاماً مثل Markdown أو BBCode بالرغم بأن هنالك مكتبات مخصصة لهذا السبب HTML Purifier.

Sanitization Filters

Unserialization

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

إذا كان لابد أن تقوم بعمل unserialize لبيانات من مصادر غير موثوقة، عندها قم باستخدام خيار allowed_classes لتحديد أي نوع من الكائنات يمكن أن يتم عمل unserialize عليه. متوفر في إصدارة PHP7 فقط

التحقق

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

Validation Filters

ملفات الضبط

عندما تقوم بإنشاء ملف ضبط لتطبيقك، فهنالك أفضل الممارسات التي ينصح بتطبيق إحداها:

Register Globals

وهو خيار ضبط في إعدادات PHP **ملاحظة: منذ الإصدارة PHP 5.4.0 تم إزالة خيار ضبط register_globals تمام. وتم إدراج هذا الفصل بمثابة تحذير لكل من ينوي الترقية لتطبيق متوافق مع إصدار قديم.

عندما يتم تفعيل register_globals، فسيقوم بإنشاء عدد من المتغيرات من متغيرات عامة من: $_POST و $_GET و $_REQUEST وجعلها متوفرة في النطاق العام لتطبيقك. ويتسبب بسهولة إلى مشاكل في الحماية فلا يتمكن تطبيقك من التأكد من مصدر البيانات ومن أين تأتي.

مثلاً: $_GET['foo'] سيكون متوفراً بالإسم $foo مما يتسبب في الكتابة على المتغيرات التي لم يتم تعريفها. فإذا كنت تستخدم إصدارة أقل من PHP 5.4.0 قم بالتأكد من أن الخيار register_globals غير مفعل.

تدوين وتقرير الأخطاء

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

بيئة التطوير

لإظهار أي خطأ يحدث أثناء التطوير، قم بضبط الخيارات في php.ini كالاتي:

display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On

إسناد القيمة -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

بيئة العمل النهائي

لإخفاء الأخطاء في بيئة العمل النهائية قم بضبط الخيارات في php.ini كالآتي:

display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On

بخيارات الضبط هذه في بيئة العلم النهائية، سيتم تدوين الأخطاء في سجل الأخطاء في المخدم ولكن لن يظهر أي منها للتمسخدم. للمزيد من المعلومات عن هذه الخيارات، قم بالإطلاع عليها في دليل PHP:

للأعلى

التجربة والإختبار

يعتبر كتابة الإختبارات التلقائية لكود PHP هو من أفضل الممارسات التي تؤدي لتطبيقات مبنية بصور صحيحة. الإختبارات التلقائية هي أداة ممتازة للتأكد من أن تطبيقك لن يتوقف عندما تقوم بإدراج أو إضافة خواص وعمليات جديدة ويجب عدم إهمالها!

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

التطوير الموجه بالاختبار TDD

مقتبس من ويكيبيديا Test Driven Development بالعربية: بالإنجليزية:

تطوير موجه بالاختبار (بالإنجليزية: Test-driven development (TTD))، هو مصطلح يطلق على إحدى عمليات تطوير البرمجيات التي تعتمد على تكرار دورة تطوير قصيرة جداً: بدايةً، يقوم المبرمج بكتابة حالة فحص أوتوماتيكية فاشلة ويجب على حالة الفحص هذه أن تعرّف تحسينا معينا أو وظيفة جديدة. ومن ثم يقوم بكتابة الشيفرة التي تجعل حالة الفحص ناجحة وأخيرا يقوم بإعادة تصنيع الشيفرة كي تتلاءم مع المعايير.

هنالك بضع أنواع مختلفة من الإختبارات التي يمكن تنفيذها على تطبيقك:

إختبار الوحدة

Unit Testing هو طريقة برمجية للتأكد من أن الدوال والكلاسات والعمليات يعملون كما يجب، ابتداءً من نقطة بنائهم وطول فترة وجودهم في دائرة التطوير. وذلك عن طريق إختبار القيم المدخلة والمخرجة من دوال والعمليات لضمان أن المنطق الداخلي يعمل بصورة صحيحة. باستخدام حقن التوابع Dependency Injection وبناء بيانات افتراضية “mock” من كلاسات وصفات، تمكنك من التأكد بأن التوابع مستخدمة بطريقة مثلى في تغطية الإختبار.

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

الإستخدام الآخر لوحدات الإختبار هو المشاركة في مشاريع مفتوحة المصدر. إذا كان يمكنك كتابة إختبار يظهر فشل وظيفة معينة، عندها قم بإصلاح هذا الخطأ ثم اظهر نجاح الإختبار، فعندها التعديلات يتم قبولها بسرعة. إذا كان لديك مشروع يقبل طلبات الدمج pull requests عندها يجب اقتراح اختبار الوحداك كمطلب أساسي.

PHPUnit هو إطار عمل إختباري لكتابة الإختبارات لتطبيقات PHP ولكن هنالك بضع بدائل أخرى:

الإختبارات المتكاملة

من ويكيبيديا بالإنجليزية:

الإختبارات المتكاملة (يطلق عليها التكامل والإختبار بعض الأحيان ويرمز لها بالإختصار “I&T”) وهو في مرحلة إختبار البرنامج بحيث يتم دمج دول البرنامج وإختبارها كمجموعة متكاملة. وتحدث بعد إختبار الوحدات وقبل إختبار التحقق. الإختبارات المتكاملة تأخذ كمعطيات الدوال التي تم تطبيق إختبار وحدة عليها ثم جمعها معاً في تجميعه تتوائم مع خطة تجميع الوظائف سوياً ثم إخراج مخرجات جاهزة لإختبار النظام.

العديد من الأدوات التي تستخدم في اختبار الوحدات يمكن استخدامها في الإختبارات المتكاملة فهما يتشابهان في عديد من المفاهيم الأساسية.

الإختبار الوظيفي

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

أدوات الإختبار الوظيفي

التطوير الموجه بالسلوك BDD

Behavior Driven Development. هنالك نوعان من هذا النمط: SpecBDD و StoryBDD. SpecBDD: يركز على السلوك التقني للكود. StoryBDD: يركز على الخواص والتفاعلات الفعلية. هنالك إطارا عمل لكلا النوعين.

باستخدام StoryBDD يمكن كتابة قصص مقروءة تقوم بوصف سلوك التطبيق. هذه القسس يمكن ان تقوم بتنفيذ إختبارات حقيقية للتطبيق. إطار العمل المستخدم في تطبيقات PHP للنوع StoryBDD Behat وتم استيحائه من مشروع Cucumber في Ruby.

باستخدام SpecBDD يمكن كتابة مواصفات تصف كيف يجب أن يكون سلوك الكود الفعلي. فبدلاً من إختبار الدالة أو العملية، فأنت تقوم بوصف سلوك الدالة أو العملية. يوجد في PHP إطار عمل PHPSpec لنفس الغرض. هذا الإطار تم استيحائه من مشروع RSpec project في Ruby.

روابط BDD

أدوات الإختبار المتكاملة

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

روابط الأدوات

للأعلى

السيرفرات والنشر

يمكن لتطبيقات PHP ان تنشر وتعمل على سيرفرات عمل نهائية بعدة طرق. PHP applications can be deployed and run on production web servers in a number of ways.

Platform as a Service (PaaS)

أو المنصة كخدمة وتوفر النظام ومعمارية الشبكة اللازمة لتشغيل تطبيق PHP على الويب. هذا يعني انه لا يوجد ضبط لتشغيل تطبيقات PHP أو أطر عمل PHP.

مؤخراً صار PaaS طريقة مشهورة لنشر واستضافة وتطوير تطبيقات PHP بكل الأحجام. يمكن ايجاد قائمة ببعض هذه المنصات PHP PaaS “Platform as a Service” providers في فصل المصادر resources section.

السيرفرات المخصصة أو الإفتراضية

Virtual or Dedicated Servers إذا كنت مرتاح بالعمل كمشرف نظام أو مهتم بتعلمه فالسيرفرات المخصصة والإفتراضية تتيح لك مطلق الحرية والتحكم في بيئة التطبيق النهائية.

nginx و PHP-FPM

تقترن PHP مع nginx باستخدام البنية المدمجة FastCGI Process Manager (FPM) وهو سيرفر خفيف ذو كفاءة عالية. ويقوم باستخدام ذاكرة أقل من نظيره Apache ويقوم بإدارة عدد أكبر من الطلبات المتزامنة. وهو مناسب في السيرفرات الإفتراضية بحيث لا يوجد الكثير من الذاكرة لإهدارها.

Apache و PHP

تملك 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. هذا الضبط سيكون ذا تأثير واضح وكبير على الذاكرة وسرعة ملحوظة ولكن هنالك جهد أكبر للتنصيب.

السيرفرات المشتركة

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

الرجاء التأكد من أن السيرفرات المشتركة توفر آخر إصدارة من PHP، قم بمعرفة إسدارات PHP.

بناء ونشر التطبيقات

إذا وجدت نفسك تقوم بتغيير مخططات قاعدة البيانات يدوياً أو تشغيل الإختبارات يدوياً قبل تحديث الملفات (يدوياً) فعليك التفكير مرة اخرى. في كل مرة تقوم فيها بتحديث تطبيقك إلى نسخة أحدث يدوياً، هنالك فرصة لحدوث خطأ. سواء كنت تتعامل مع وسيلة سهلة للتحديث و أو عملية بناء شاملة أو حتى خطة تكامل مستمرة 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.

المزيد من القراءة:

الربط المستمر Continuous Integration

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

– مارتين فولر

هنالك طرق مختلفة لتطبيق الربط المستمر في PHP. يعد Travis CI من أفضلهم فهو يقوم بتحقيق الربط المتواصل بشكل حتى للمشاري الصغيرة. وهو عبارة عن خدمة مستضافة لمجتمع المصدر المفتوح. وترتبط مع GitHub وتوفر دعم من الدرجة الأولى للعديد من اللغات من ضمنها PHP.

المزيد من القراءة:

للأعلى

الإفتراضية

تشغيل التطبيق على بيئات مختلفة من تلك التي في بيئة التطوير والعمل النهائي تسبب في ظهور أخطاء غريبة. ومن الصعب إدارة البيئات المختلفة محدثة وتعمل بنفس الإصدارات لكل المكتبات عندما يكون التطوير في فريق.

إذا كنت تقوم بالتطوير على Windows وتقوم بالنشر على Linux أو أي شيء غير ويندوز أو يتم التطوير في فريق يجب عليك استخدام آلات افتراضية. قد يكون غريباً بعض الشء ولكن بجانب الإفتراضية المعروفة للبيئة مثل برامج VMWare و VirtualBox هنالك أدوات إضافية تساعد في إنشاء بيئة إقتراضية بخطوات سهلة وبسيطة.

Vagrant

يساعد Vagrant على بناء صناديق افتراضية فوق ما يعرف بالبيئة الإفتراضية Virtual Environment ويتم ضبط هذه البيئة بناءً على ملف ضبط واحد. هذه الصناديق يمكن تنصيبها بشكل يدوي أو باستخدام أدوات “التموين” مثل Puppet أو Chef. تموين الصناديق هو طريقة فعالة لضمان أن جميع الصناديق تعمل بشكل متساوي وتزيل كل التعقيدات لتنصيب الأوامر. ويمكن أيضاً تدمير الصناديق وإعادة إنشائها بدون أي خطوات يدوية مما يجعل من السهل انشاء نسخ جديدة.

يقوم Vagrant بانشاء مجلدات لكي تقوم بمشاركة الكود مابين الجهاز الحلي والجهاز الإفتراضي مما يعني أنه يمكن إنشاء وتعديل ملفاتك وتنفيذها من الجهاز الحالي من دون الحاجة للدخول للجهاز الإفتراضي.

القليل من المساعدة

إذا كنت تريد المساعدة للبدء في استخدام Vagrant هنالك بعض الخدام التي قد تكون مفيدة لك:

Docker

بجانب استخدام Vagrant، هنالك طريقة سهلة اخرى لتشغيل بيئة تطوير أو نهائية إفتراضية وهي باستخدام Docker. فهو يساعد بتوفير حاويات لينكس لكل أنواع التطبيقات. هنالك العديد من تصاوير Docker التي توفر لك خدمات اخرى جيدة بدون الحاجة لتنصيب تلك الخدمات على الجهاز المحلي مثل قواعد بيانات MySQL أو PostgreSQL والكثير غيرهما. قم بالإطلاع على Docker Hub Registry للبحث في القوائم عن التصاوير المبنية مسبقاً للحاويات التي يمكن تشغيلها بخطوات بسيطة.

مثال: تنفيذ تطبيق PHP في Docker

بعد تنصيب docker على الجهاز المحلي يمكن تشغيل Apache مع دعم PHP في خطوة واحدة. الأمر التالي سيقوم بتنزيل توزيعة Apache مع آخر إصدارة من PHP وإتاحة المجلد /path/to/your/php/files للوصول عن طريق http://localhost:8080:

docker run -d --name my-php-webserver -p 8080:80 -v /path/to/your/php/files:/var/www/html/ php:apache

بعد تنفيذ docker run عندها الحاوية تكون إنشئت وقيد العمل. إذا كنت تريد إيقاف أو تشغيل الحاوية مرة أخرى يمكن استخدام الإسم المقرون وببساطة تنفيذ docker stop my-php-webserver و docker start my-php-webserver بدون إدراج الأوامر المذكورة أعلاه مرة أخرى.

إعرف المزيد عن Docker

الأمر المذكور أعلاه يقوم فقط بإظهار طريقة سريعة لتشغيل سيرفر Apache مع دعم PHP ولكن هنالك العديد من الأشياء التي يمكن عملها باستخدام Docker. واحدة من أهم هذه الأشياء لمطوري PHP هو ربط سيرفر الويب بقاعدة بيانات، مثلاً. كيفية عمل هذا قد تم شرحه في دليل Docker Docker User Guide.

للأعلى

التخزين المؤقت

تعتبر 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
// قم بالتأكد من أن هنالك بيانات مخزنة مؤقتاً باسم 'expensive_data'
$data = apc_fetch('expensive_data');
if ($data === false) {
    // البيانات غير موجودة في المخزن المؤقت، قم بحفظ النتائج المكلفة لإستخدام لاحق
    apc_add('expensive_data', $data = get_expensive_data());
}

print_r($data);

لاحظ أنه قبل إصدارة PHP 5.5 تتيح APC كل من مخازن كائنات ومخازن bytecode. APCu هو مشروع لجلب مخازن الكائنات إلى PHP 5.5+ لأنه الآن PHP لديها مخازن bytecode مدمج (OPcache).

تعرف المزيد عن أنظمة تخزين الكائنات المشهورة:

للأعلى

توثيق المصدر البرمجي

PHPDoc

يعتبر PHPDoc هو معيار قياسي غير رسمي لتوثيق كود PHP. هنالك العديد من والوسوم المختلفة tags. القائمة الكاملة لهذه الوسوم مع الأمثلة موجودة في الدليل الرسمي PHPDoc manual.

أدناه مثال لكيفية توثيق كلاس بداخله بضع عمليات:

<?php
/**
 * @author A Name <a.name@example.com>
 * @link http://www.phpdoc.org/docs/latest/index.html
 */
class DateTimeHelper
{
    /**
     * @param mixed $anything Anything that we can convert to a \DateTime object
     *
     * @throws \InvalidArgumentException
     *
     * @return \DateTime
     */
    public function dateTimeFromAnything($anything)
    {
        $type = gettype($anything);

        switch ($type) {
            // Some code that tries to return a \DateTime object
        }

        throw new \InvalidArgumentException(
            "Failed Converting param of type '{$type}' to DateTime object"
        );
    }

    /**
     * @param mixed $date Anything that we can convert to a \DateTime object
     *
     * @return void
     */
    public function printISO8601Date($date)
    {
        echo $this->dateTimeFromAnything($date)->format('c');
    }

    /**
     * @param mixed $date Anything that we can convert to a \DateTime object
     */
    public function printRFC2822Date($date)
    {
        echo $this->dateTimeFromAnything($date)->format('r');
    }
}

هذا التوثيق للكلاس بأكمله به وسم @author و @link. فوسم @author يستخدم لتوثيق محرر الكود ويمكن تكراره لتوثيق عده محررين. والوسم @link يستخدم لربط موقع يوضح العلاقة ما بين الموقع والكود.

بداخل الكلاس في العملية الأولى بها وسم @param لتوثيق نو واسم ووصف المعطى الممر للعملية. بالإضافة لوسمي @return و @throws لتوثيق نوع الإرجاع وتوضيح أي إستثناءات يمكن رميها.

العملية الثانية والثالثة متماثلتين فلديهما الوسم @param كما في العملية الأولى. الإختلاف المهم ما بين العملية الثانية والثالثة هي وجود/عدم وجودة وسم@return. @return void تعدي تنبيهنا بأنه لا يوجد مخرجات، وأيضاً إهمال كتابة @return void يعطي نفس النتيجة (لا يوجد مرتجعات من العملية).

للأعلى

المصادر

من المصادر الأصلية

أشخاص تتابعهم

من الصعب إيجاد أعضاء في مجتمع PHP ذوي خبرة وعلم كبيرين في البداية. يمكن إيجاد قائمة جيدة من أعضاء مجتمع PHP وحساباتهم تويتر في:

الإشراف والتوجيه

مزودي PHP PaaS

للإطلاع على أي نسخة تعمل هذه الخدمات قم بالذهاب الى هنا PHP Versions.

أطر العمل

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

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

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

العديد من أطر العمل تضيف عدد من المميزات على قالب أطر العمل الصغير وهذه الأطر هي أطر العمل الكاملة. وعادة ما يكون مدمجاً فيها حزم ORM و مصداقة وتحقق.

أطر عمل المكونات عادة ما تكون تجميعة من مكتبات مخصصة لعمل وظيفة محددة. يمكن استخدام بضع منها سوياً لعمل أطار عمل صغير أو كامل.

المكونات

كما هو مذكور أعلاه “المكونات” هي هدف معروف لإنشاء ونشر وزرع ومشاركة الكود. العديد من حاويات المكونات موجودة بالفعل اشهرها:

كلاهما حاويات لديها أدوات سطور أوامر تساعدك لتنصيب وتحديث وترقية المكونات وقد تم شرحها في فصل Dependency Management.

هنالك أيضاً مكونات خاصة بأطر عمل ومزودين والتي لا تتيح أي أطار عمل على الإطلاق. هذه المشاريع توفع مصادر اخرى من الحزم المتطابقة مع القليل من الإعتمادية على حزم أخرى أو أطر عمل معينة.

مثلاً يمك استخدام FuelPHP Validation package “حزمة للتحقق” من دون الحاجة لاستخدام أطار عمل FuelPHP.

Illuminate components قريباً سيتم عزله من إطار عمل Laravel. حتى الآن أفضل المكونات المعزولة من إطار عمل Laravel قد تم سردها أعلاه.

مصادر أخرى مفيدة

أوراق غش

المزيد من أفضل الممارسات

عالم PHP

دروس فيديو

قنوات Youtube

دروس فيديو مدفوعة

كتب

هنالك العديد من كتب 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

مجموعات مستخدمي PHP

إذا كنت تعيش في مدينة كبيرة، هنالك العديد من مجموعات 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

مجتمع PHP يقوم باستضافة مؤتمرات عالمية ومحلية في العديد من المدن حول العالم. عادة ما يتحدث فيها اعضاء مجتمع PHP المعروفين وهي فرصة ممتازة للتعلم مباشرة من قائدي المنشأة.

قم بإيجاد مؤتمر PHP

فيلة PHP

ElePHPant وهي جالبة الحظ لكل مشروع PHP مع الفيل في تصميمها. تم تصميمها في الأساس لمشروع PHP في عام 1998 من قبل فاينسنت بونتير وهو الأب لكل فيلة PHP حول العالم بعد عشر سنوات تم تجسيمها كدمية. الآن فيلة PHP موجودة في العديد من مؤتمرات PHP ويمتلكها العديد من مطوري PHP في أجهزتهم لمجرد المرح والإيحاء.

مقابلة مع فاينسنت بونتير