العام، المحمي، الخاص (Public, Protected, Private)
جزء من قسم Object Oriented Programming في رحلة PHP على Coddy — الدرس 38 من 91.
مرحباً بكم في فصل التغليف (Encapsulation)! التغليف (Encapsulation) يدور حول التحكم في الوصول إلى البيانات الداخلية للفئة (class) الخاصة بك. توفر PHP ثلاثة معدلات وصول (access modifiers) تحدد من أين يمكن الوصول إلى الخصائص (properties) والأساليب (methods): public، و protected، و private.
إليك كيفية عمل كل معدل:
<?php
class BankAccount {
public $accountHolder; // يمكن الوصول إليه من أي مكان
protected $accountNumber; // يمكن الوصول إليه في هذا الكلاس والكلاسات التابعة
private $balance; // يمكن الوصول إليه فقط داخل هذا الكلاس
public function __construct($holder, $number, $balance) {
$this->accountHolder = $holder;
$this->accountNumber = $number;
$this->balance = $balance;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount("John", "12345", 1000);
echo $account->accountHolder . "\n"; // يعمل - public
echo $account->getBalance(); // يعمل - ميثود عامة (public method)
المخرجات:
John
1000ستؤدي محاولة الوصول إلى $account->balance مباشرة إلى حدوث خطأ لأنها private. وينطبق الشيء نفسه على $account->accountNumber من خارج تسلسل الـ class. تضمن هذه الحماية إمكانية تعديل البيانات الحساسة فقط من خلال methods محكومة.
| المعدل | نفس الفئة | الفئة التابعة | من الخارج |
|---|---|---|---|
public | نعم | نعم | نعم |
protected | نعم | نعم | لا |
private | نعم | لا | لا |
نقطة رئيسية: استخدم private للبيانات الداخلية التي لا ينبغي الوصول إليها مباشرة، و protected للبيانات التي تحتاجها الفئات الفرعية، و public فقط للوصول الخارجي الآمن.
التحدي
سهللنقم ببناء نظام آمن لإدارة الموظفين يوضح كيف تحمي محددات الوصول (access modifiers) البيانات الحساسة. ستقوم بإنشاء تسلسل هرمي للفئات (class hierarchy) حيث يمكن الوصول إلى مستويات مختلفة من المعلومات اعتماداً على مكان تشغيل الكود — داخل الفئة، أو في فئة تابعة (child class)، أو من الخارج.
ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:
Employee.php— أنشئ فئةEmployeeتدير بيانات الموظفين بمستويات رؤية مناسبة. يجب أن تحتوي الفئة على:- خاصية
publicتسمى$nameلاسم الموظف (آمنة ليراها الجميع) - خاصية
protectedتسمى$employeeIdللمعرف الداخلي (تحتاجه الفئات التابعة) - خاصية
privateتسمى$salaryلمعلومات الراتب الحساسة (يجب أن تصل إليها هذه الفئة فقط بشكل مباشر)
getSalary()تعيد الراتب الخاص — هذه هي الطريقة المحكومة للوصول إلى البيانات المحمية. أضف أيضاً طريقة عامة باسمgetPublicInfo()تعيد"[name] works here".- خاصية
Manager.php— أنشئ فئةManagerترث منEmployee. قم بتضمين ملف Employee. يجب أن يقبل المنشئ الاسم، و employeeId، والراتب، واسم القسم. استدعِ منشئ الفئة الأب بالقيم الثلاث الأولى، ثم خزن القسم في خاصية خاصة (private). أضف طريقة عامة باسمgetTeamInfo()تعيد"Manager [name] (ID: [employeeId]) leads [department]". لاحظ كيف يمكن للفئة التابعة الوصول إلى$employeeIdالمحمي ولكنها ستحتاج إلىgetSalary()للوصول إلى الراتب الخاص.main.php— قم بتضمين ملف Manager. ستتلقى أربعة مدخلات: اسم، ومعرف موظف، وراتب (كسلسلة نصية ستقوم بتحويلها إلى عدد صحيح)، واسم قسم. أنشئ كائناً (instance) منManagerبهذه القيم. اطبع ثلاثة أسطر:- اسم المدير الذي تم الوصول إليه مباشرة (خاصية عامة)
- نتيجة استدعاء
getTeamInfo() - نتيجة استدعاء
getSalary()
يوضح هذا التحدي مفهوم التغليف (encapsulation) بشكل عملي: الاسم متاح بحرية، ومعرف الموظف مشترك مع الفئات التابعة من خلال الرؤية المحمية (protected)، ويظل الراتب مقفلاً في الفئة الأب — ولا يمكن الوصول إليه إلا من خلال طريقة عامة محكومة.
ورقة مرجعية
يوفر PHP ثلاثة معدلات وصول (access modifiers) للتحكم في الأماكن التي يمكن من خلالها الوصول إلى الخصائص والأساليب (methods):
| المعدل (Modifier) | نفس الفئة (Same Class) | الفئة الابنة (Child Class) | من الخارج (Outside) |
|---|---|---|---|
public | نعم | نعم | نعم |
protected | نعم | نعم | لا |
private | نعم | لا | لا |
مثال:
<?php
class BankAccount {
public $accountHolder; // Accessible from anywhere
protected $accountNumber; // Accessible in this class and child classes
private $balance; // Accessible only in this class
public function __construct($holder, $number, $balance) {
$this->accountHolder = $holder;
$this->accountNumber = $number;
$this->balance = $balance;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount("John", "12345", 1000);
echo $account->accountHolder; // Works - public
echo $account->getBalance(); // Works - public method
أفضل الممارسات:
- استخدم
privateللبيانات الداخلية التي لا ينبغي الوصول إليها مباشرة - استخدم
protectedللبيانات التي تحتاجها الفئات الابنة - استخدم
publicفقط للوصول الخارجي الآمن
جرّب بنفسك
<?php
require_once 'Manager.php';
// قراءة المدخلات
$name = trim(fgets(STDIN));
$employeeId = trim(fgets(STDIN));
$salary = intval(trim(fgets(STDIN)));
$department = trim(fgets(STDIN));
// TODO: إنشاء مثيل (instance) من Manager باستخدام قيم المدخلات
// TODO: طباعة اسم المدير (يتم الوصول إليه مباشرة كخاصية عامة)
// TODO: طباعة نتيجة استدعاء getTeamInfo()
// TODO: طباعة نتيجة استدعاء getSalary()
?>يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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)