منصة التعليم الإلكتروني
جزء من قسم Object Oriented Programming في رحلة PHP على Coddy — الدرس 88 من 91.
التحدي
سهللنقم ببناء منصة تعليم إلكتروني (E-Learning Platform) تدير الدورات التدريبية، والطلاب، والمحاضرين. يجمع هذا التحدي الشامل بين الوراثة (inheritance)، والواجهات (interfaces)، والكبسلة (encapsulation)، وأنماط التصميم في نظام متماسك.
ستقوم بتنظيم الكود الخاص بك عبر ستة ملفات:
User.php— أنشئ فئة مجردة (abstract class) باسمUserتعمل كقاعدة لكل من الطلاب والمحاضرين. استخدم خاصية constructor promotion لكل منid(int) وname(string)، وكلاهما public readonly. قم بتضمين تابع مجرد (abstract method) باسمgetRole(): stringيجب على الفئات التابعة تنفيذه.Student.php— قم بتضمين ملف User. أنشئ فئةStudentترث منUser. يتتبع الطلاب دوراتهم المسجلة في مصفوفة خاصة (private array) وتقدمهم (نسبة مئوية مكتملة) لكل دورة. قم بتنفيذ ما يلي:getRole(): string— يعيد"Student"enrollInCourse(Course $course): string— يسجل الطالب إذا كانت الدورة بها سعة شاغرة؛ ويعيد رسالة نجاح أو فشلgetEnrolledCourses(): array— يعيد مصفوفة الدورات المسجلةupdateProgress(string $courseTitle, int $percent): void— يحدد التقدم لدورة معينة (0-100)getProgress(string $courseTitle): int— يعيد نسبة التقدم، أو 0 إذا لم يكن مسجلاً
Instructor.php— قم بتضمين ملف User. أنشئ فئةInstructorترث منUser. يمكن للمحاضرين إنشاء وإدارة الدورات. قم بتنفيذ ما يلي:getRole(): string— يعيد"Instructor"createCourse(string $title, int $capacity): Course— ينشئ ويعيد كائن Course جديد مع تعيين هذا المحاضر له
Course.php— قم بتضمين ملف Instructor. أنشئ فئةCourseمع استخدام constructor promotion لـtitle(string, public readonly)، وinstructor(Instructor, public readonly)، وcapacity(int, private). تتبع الطلاب المسجلين في مصفوفة خاصة. قم بتنفيذ ما يلي:getCapacity(): int— يعيد السعة القصوىgetEnrolledCount(): int— يعيد عدد المسجلين الحاليينhasCapacity(): bool— يعيد true إذا كان بإمكان المزيد من الطلاب التسجيلaddStudent(Student $student): bool— يضيف طالباً إذا سمحت السعة، ويعيد حالة النجاحgetStudents(): array— يعيد مصفوفة الطلاب المسجلين
Platform.php— قم بتضمين ملفي Course و Student. أنشئ فئةPlatformتدير النظام بأكمله. قم بتخزين الدورات والمستخدمين في مصفوفات خاصة. قم بتنفيذ ما يلي:addCourse(Course $course): void— يضيف دورة إلى المنصةfindCourse(string $title): ?Course— يبحث عن دورة بواسطة العنوانenrollStudent(Student $student, string $courseTitle): string— يسجل طالباً في دورة. يعيد"Course not found"، أو"Course is full"، أو"[name] enrolled in [title]"getCourseStats(string $title): string— يعيد"[title]: [enrolled]/[capacity] students"أو"Course not found"
main.php— قم بتضمين ملف Platform. ستتلقى ثلاثة مدخلات: بيانات المحاضر (JSON)، والدورات المراد إنشاؤها (JSON)، والعمليات المراد تنفيذها (JSON).تنسيق JSON للمحاضر:
{"id": 1, "name": "Dr. Smith"}تنسيق JSON للدورات:
[{"title": "PHP Basics", "capacity": 2}, {"title": "OOP Mastery", "capacity": 3}]تنسيق JSON للعمليات:
[{"type": "enroll", "student_id": 1, "student_name": "Alice", "course": "PHP Basics"}, {"type": "progress", "student_id": 1, "course": "PHP Basics", "percent": 50}, {"type": "stats", "course": "PHP Basics"}]أنشئ المنصة، والمحاضر، وجميع الدورات (باستخدام تابع
createCourseالخاص بالمحاضر). أضف الدورات إلى المنصة. ثم قم بمعالجة كل عملية:"enroll"— أنشئ طالباً جديداً وقم بتسجيله؛ واطبع النتيجة منenrollStudent()"progress"— حدث تقدم الطالب؛ واطبع"[name] progress in [course]: [percent]%""stats"— اطبع النتيجة منgetCourseStats()
تتبع الطلاب الذين تم إنشاؤهم بواسطة معرفاتهم (ID) حتى تتمكن من تحديث تقدمهم لاحقاً. اطبع نتيجة كل عملية في سطر جديد.
يوضح هذا التحدي كيف تخلق الوراثة تسلسلاً هرمياً نظيفاً للمستخدمين، وكيف تحمي الكبسلة بيانات التسجيل، وكيف تعمل المنصة كمنسق يدير العلاقات بين الدورات والطلاب والمحاضرين.
جرّب بنفسك
<?php
require_once 'Platform.php';
// قراءة المدخلات
$instructorData = (array)json_decode(trim(fgets(STDIN)), true);
$coursesData = (array)json_decode(trim(fgets(STDIN)), true);
$operations = (array)json_decode(trim(fgets(STDIN)), true);
// TODO: إنشاء المنصة
// TODO: إنشاء المحاضر من instructorData
// TODO: إنشاء جميع الدورات التدريبية باستخدام طريقة createCourse الخاصة بالمحاضر
// وإضافتها إلى المنصة
// TODO: تتبع الطلاب الذين تم إنشاؤهم من خلال معرفاتهم (ID)
$students = [];
// TODO: معالجة كل عملية
foreach ($operations as $op) {
$operation = (array)$op;
// TODO: معالجة عملية "enroll"
// إنشاء طالب جديد وتسجيله
// طباعة النتيجة من enrollStudent()
// TODO: معالجة عملية "progress"
// تحديث تقدم الطالب
// طباعة "[name] progress in [course]: [percent]%"
// TODO: معالجة عملية "stats"
// طباعة النتيجة من getCourseStats()
}
?>جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةمقدمة في OOPClasses مقابل Objectsالكلمة المفتاحية $thisالـ Methodsالـ Propertiesالمنشئ (__construct)الهادم (__destruct)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسيةالكلمة المفتاحية parent::إعادة تعريف الدوال (Method Overriding)الكلمة المفتاحية finalالأصناف المجردة (Abstract Classes)مراجعة - هيكلية الموظفين7التغليف (Encapsulation)
العام، المحمي، الخاص (Public, Protected, Private)نظرة متعمقة على معدلات الوصولدوال Getters و Settersإخفاء المعلوماتميزة Constructor Promotion (8.0)مراجعة - نظام سجلات الطلاب10مفاهيم البرمجة كائنية التوجه المتقدمة
التركيب مقابل الوراثةحقن التبعيةالأصناف المجهولةالتعدادات (PHP 8.1)الألياف (PHP 8.1)تعمق في استنساخ الكائناتالمولدات والمكررات13أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع2مساحات الأسماء والتحميل التلقائي
مقدمة إلى مساحات الأسماءالكلمة المفتاحية useمعيار التحميل التلقائي PSR-4أداة التحميل التلقائي Composerملخص - مشروع منظم5الواجهات والعقود
مقدمة إلى الواجهاتتنفيذ الواجهاتتنفيذ واجهات متعددةالواجهة مقابل الـ Abstract Classالـ Type Hinting مع الواجهاتملخص - حاسبة الأشكال8الميثودات السحرية (Magic Methods)
مقدمة في الميثودات السحرية__toString و __debugInfo__get, __set, __isset, __unset__call و __callStatic__clone واستنساخ الكائنات__serialize و __unserializeمراجعة - Custom Collection3خصائص الكلاس
خصائص الـ Instance مقابل الخصائص الساكنة (Static)الثوابت في الكلاساتالدوال والخصائص الساكنة (Static)الخصائص الخاصة (Private) والمحمية (Protected)خصائص للقراءة فقط (Readonly) في PHP 8.1مراجعة - مدير الحساب البنكي6تعدد الأشكال (Polymorphism)
مراجعة إعادة تعريف الدوال (Method Overriding)تعدد الأشكال عبر الـ Interfacesتلميح النوع (Type Hinting) وأنواع الاتحاد (Union Types)الربط الاستاتيكي المتأخر (Late Static Binding)ملخص - معالج الدفع (Payment Processor)