Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

العام، المحمي، الخاص (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 فقط للوصول الخارجي الآمن.

challenge icon

التحدي

سهل

لنقم ببناء نظام آمن لإدارة الموظفين يوضح كيف تحمي محددات الوصول (access modifiers) البيانات الحساسة. ستقوم بإنشاء تسلسل هرمي للفئات (class hierarchy) حيث يمكن الوصول إلى مستويات مختلفة من المعلومات اعتماداً على مكان تشغيل الكود — داخل الفئة، أو في فئة تابعة (child class)، أو من الخارج.

ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:

  • Employee.php — أنشئ فئة Employee تدير بيانات الموظفين بمستويات رؤية مناسبة. يجب أن تحتوي الفئة على:
    • خاصية public تسمى $name لاسم الموظف (آمنة ليراها الجميع)
    • خاصية protected تسمى $employeeId للمعرف الداخلي (تحتاجه الفئات التابعة)
    • خاصية private تسمى $salary لمعلومات الراتب الحساسة (يجب أن تصل إليها هذه الفئة فقط بشكل مباشر)
    يجب أن يقبل المنشئ (constructor) جميع القيم الثلاث ويقوم بتعيينها. أضف طريقة عامة (public method) باسم 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()
?>
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming