Skip to content

2. نهج تطوير MVC في الويب/PHP

نقترح هنا نهجًا لتطوير تطبيقات الويب/PHP التي تتوافق مع بنية MVC. وهذا النهج موجود فقط لفتح آفاق جديدة. وسيقوم القارئ بتكييفه وفقًا لذوقه واحتياجاته.

  1. سنبدأ بتحديد جميع طرق عرض التطبيق. وهي عبارة عن صفحات الويب التي تظهر للمستخدم. سنضع أنفسنا في مكان المستخدم لرسم طرق العرض. نتميز بين ثلاثة أنواع من طرق العرض:
    • نموذج الإدخال الذي يهدف إلى الحصول على معلومات من المستخدم. ويحتوي هذا النموذج عمومًا على زر لإرسال المعلومات المدخلة إلى الخادم.
    • صفحة الرد التي لا تخدم سوى تقديم المعلومات للمستخدم. غالبًا ما تحتوي هذه الصفحة على رابط واحد أو أكثر يسمح للمستخدم بمتابعة التطبيق بصفحة أخرى.
    • الصفحة المختلطة: أرسل المتحكم إلى العميل صفحة تحتوي على معلومات قام بتوليدها. ستستخدم هذه الصفحة نفسها من قبل العميل لتزويد المتحكم بمعلومات جديدة من المستخدم.
  1. ستنشأ عن كل عرض صفحة PHP. بالنسبة لكل منها:
    • سنرسم شكل الصفحة
    • سيتم تحديد الأجزاء الديناميكية منها:
      • المعلومات الموجهة للمستخدم والتي يجب أن يوفرها وحدة التحكم كمعلمات للعرض PHP. الحل البسيط هو التالي:
        • يضع وحدة التحكم في قاموس $dReponse المعلومات التي يريد توفيرها لعرض V
        • يقوم المتحكم بعرض العرض V. إذا كان هذا العرض يتوافق مع الملف المصدر V.php، يتم الحصول على هذا العرض ببساطة من خلال الأمر include V.php.
        • التضمين السابق هو تضمين كود في وحدة التحكم. يمكن الوصول إلى القاموس $dReponse الذي تم ملؤه بواسطة وحدة التحكم مباشرةً من خلال كود V.php.
      • بيانات الإدخال التي يجب إرسالها إلى البرنامج الرئيسي للمعالجة. يجب أن تكون هذه البيانات جزءًا من نموذج HTML (علامة <form>).
  1. يمكننا تمثيل مدخلات ومخرجات كل عرض بشكل تخطيطي
  • المدخلات هي البيانات التي يجب أن يوفرها وحدة التحكم للصفحة PHP
  • المخرجات هي البيانات التي يجب أن توفرها الصفحة PHP لوحدة التحكم في التطبيق. وهي جزء من نموذج HTML وسيستردها وحدة التحكم من خلال عملية من النوع $_GET["param"] (طريقة GET) أو $_POST["param"] (طريقة POST).
  1. في كثير من الأحيان، لا تكون الصفحة النهائية المرسلة إلى العميل عبارة عن عرض واحد، بل مجموعة من العروض. على سبيل المثال، قد تكون الصفحة المرسلة إلى المستخدم بالشكل التالي:

قد تكون المنطقة 1 شريط عنوان، والمنطقة 2 شريط قائمة، والمنطقة 3 منطقة محتوى. في PHP، يمكن الحصول على هذا التكوين من خلال الكود HTML/PHP التالي:

<table>
    <tr>
        <td><?php include zone1.php ?></td>
    </tr>
    <tr>
        <td><?php include zone2.php ?></td>
        <td><?php include zone3.php ?></td>
    </tr>
</table>

يمكن جعل هذا الرمز ديناميكيًا بكتابة:

<table>
    <tr>
        <td><?php include $dReponse['urlZone1'] ?></td>
    </tr>
    <tr>
        <td><?php include $dReponse['urlZone2'] ?></td>
        <td><?php include $dReponse['urlZone3'] ?></td>
    </tr>
</table>

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

  • تحديد النموذج المطلوب استخدامه
  • تحديد العناصر التي يجب تضمينها فيه
  • طلب عرض النموذج
  1. سنكتب الكود PHP/HTML لكل نموذج من نماذج الرد. عادةً ما يكون الكود بسيطًا. قد يكون كود المثال أعلاه كما يلي:
<?php
    // عمليات التهيئة للاختبارات بدون وحدة تحكم
...
?>
<html>
    <head>
      <title><?php echo $dReponse['titre'] ?></title>
      <link type="text/css" href="<?php echo $dReponse['style']['url'] ?>" rel="stylesheet" />    
    </head>
  <body>      
    <table>
        <tr>
            <td><?php include $dReponse['urlZone1'] ?></td>
        </tr>
        <tr>
            <td><?php include $dReponse['urlZone2'] ?></td>
            <td><?php include $dReponse['urlZone3'] ?></td>
        </tr>
    </table>
  <body>
</html>

سنستخدم كلما أمكن ذلك ورقة أنماط حتى نتمكن من تغيير "مظهر" الاستجابة دون الحاجة إلى تعديل الكود PHP/HTML.

  1. سنكتب الكود PHP/HTML لكل عرض أساسي. وسيكون في الغالب بالشكل التالي:
<?php
     // ربما بعض التهيئات خاصة في مرحلة التصحيح
    ...
?>

<balise>
...
         // سنحاول هنا تقليل كود php
</balise>

تجدر الإشارة إلى أن العرض الأساسي يتم دمجه في نموذج. ويتم دمج رمزه HTML داخل رمز النموذج. وفي أغلب الأحيان، يتضمن هذا الأخير بالفعل العلامات <html> و<head> و<body>. ولذلك، من النادر العثور على هذه العلامات في عرض أساسي.

  1. يمكن إجراء اختبارات على مختلف نماذج الاستجابة والعروض الأساسية
  • يتم اختبار كل نموذج استجابة. إذا كان اسم النموذج هو modele1.php، فسنطلب عبر المتصفح URL http://localhost/chemin/modele1.php. يتوقع النموذج قيمًا من وحدة التحكم. هنا يتم استدعاؤه مباشرةً وليس عبر وحدة التحكم. لن يتلقى النموذج المعلمات المتوقعة. لكي تكون الاختبارات ممكنة مع ذلك، سنقوم بأنفسنا بتهيئة المعلمات المتوقعة في صفحة النموذج PHP باستخدام الثوابت.
  • يتم اختبار كل نموذج وكذلك جميع العروض الأولية. هذا هو الوقت المناسب أيضًا لوضع العناصر الأولى من أوراق الأنماط المستخدمة.
  1. ثم نكتب منطق التطبيق:
  • يدير المتحكم أو البرنامج الرئيسي عمومًا عدة إجراءات. يجب أن يتم تحديد الإجراء المطلوب تنفيذه في الطلبات التي تصل إليه. يمكن القيام بذلك عن طريق معلمة في الطلب سنسميها هنا action:
    • إذا كان الطلب قادمًا من نموذج (<form>)، فيمكن أن يكون هذا المعامل معلمة مخفية في النموذج:
<form ... action="/C/main.php" method="post"  ...>
<input type="hidden" name="action" value="uneAction">
...
</form>
  • (تابع)
    • إذا كان الطلب قادمًا من رابط، فيمكن ضبطه على النحو التالي:
 <a href="/C/main.php?action=uneAction">lien</a>

يمكن للمتحكم أن يبدأ بقراءة قيمة هذا المعامل ثم يفوض معالجة الطلب إلى وحدة مسؤولة عن معالجة هذا النوع من الطلبات. لقد وضعنا أنفسنا هنا في حالة حيث يتم التحكم في كل شيء بواسطة نص برمجي واحد يسمى main.php. إذا كان على التطبيق معالجة الإجراءات action1، action2، ...، actionx، يمكن إنشاء وظيفة لكل إجراء داخل وحدة التحكم. إذا كان هناك العديد من الإجراءات، فقد ينتهي بنا الأمر بوحدة تحكم "ديناصورية". يمكن أيضًا إنشاء نصوص برمجية action1.php، action2.php، ...،actionx.php مكلفة بمعالجة كل إجراء. وسيكتفي وحدة التحكم التي يتعين عليها معالجة الإجراء actionx بتحميل كود البرنامج النصي المقابل بواسطة تعليمة من نوع include "actionx.php". وتتمثل ميزة هذه الطريقة في العمل خارج كود وحدة التحكم. وبذلك يمكن لكل فرد من فريق التطوير العمل على البرنامج النصي لمعالجة الإجراء actionx بشكل مستقل نسبيًا. كما أن تضمين كود البرنامج النصي actionx.php في كود وحدة التحكم عند التنفيذ له ميزة أخرى تتمثل في تخفيف حجم الكود المحمّل في الذاكرة. يتم تحميل كود معالجة الإجراء الجاري فقط. يؤدي تضمين الكود هذا إلى احتمال تضارب متغيرات وحدة التحكم مع متغيرات البرنامج النصي للإجراء. سنرى أنه يمكننا العمل على قصر متغيرات وحدة التحكم على عدد قليل من المتغيرات المحددة جيدًا، والتي يجب تجنب استخدامها في البرامج النصية.

  • سنحاول بشكل منهجي عزل كود الأعمال أو كود الوصول إلى البيانات الدائمة في وحدات منفصلة. وحدة التحكم هي بمثابة قائد فريق يتلقى الطلبات من عملائه (عملاء الويب) ويقوم بتنفيذها من خلال الأشخاص الأكثر ملاءمة (وحدات الأعمال). عند كتابة وحدة التحكم، سنحدد واجهة الوحدات النمطية الخاصة بالمهام التي يجب كتابتها. هذا إذا كان يتعين إنشاء هذه الوحدات النمطية. إذا كانت موجودة بالفعل، فستتكيف وحدة التحكم مع واجهة هذه الوحدات النمطية الموجودة.
  1. سنكتب الهيكل الأساسي للوحدات النمطية الخاصة بالمجال المطلوبة للمتحكم. على سبيل المثال، إذا كان المتحكم يستخدم وحدة نمطية getCodes تعرض جدولًا من سلاسل الأحرف، فيمكننا الاكتفاء في البداية بكتابة:
function getCodes(){
    return array("code1","code2","code3");
}
  1. يمكننا بعد ذلك الانتقال إلى اختبارات وحدة التحكم ونصوص PHP المرتبطة بها:
  • يتم وضع وحدة التحكم، ونصوص الإجراءات، والنماذج، وطرق العرض، والموارد اللازمة للتطبيق (الصور،...) في المجلد DC المرتبط بسياق C للتطبيق.
  • وبعد ذلك، يتم اختبار التطبيق وتصحيح الأخطاء الأولى. إذا كان main.php هو وحدة التحكم و C هو سياق التطبيق، فسيتم طلب URL http://localhost/C/main.php. في نهاية هذه المرحلة، تصبح بنية التطبيق جاهزة للعمل. قد تكون مرحلة الاختبار هذه صعبة نظرًا لقلة أدوات تصحيح الأخطاء المتاحة إذا لم يتم استخدام بيئات تطوير متطورة والتي عادةً ما تكون مدفوعة. يمكن الاستعانة بتعليمات echo "message" التي تكتب في التدفق HTML المرسل إلى العميل، وبالتالي تظهر في صفحة الويب المعروضة بواسطة المتصفح.
  1. وأخيرًا، نكتب فئات الأعمال التي يحتاجها وحدة التحكم. وعادةً ما يكون لدينا هنا التطوير الكلاسيكي لفئة PHP التي تكون في أغلب الأحيان مستقلة عن أي تطبيق ويب. وسيتم اختبارها أولاً خارج هذه البيئة، باستخدام تطبيق وحدة التحكم على سبيل المثال. عند كتابة فئة مهنية، يتم دمجها في بنية نشر تطبيق الويب واختبار دمجها بشكل صحيح. يتم اتباع هذه الخطوات لكل فئة مهنية.