Public, Private, Protected في PHP: لماذا بدونها يصبح كودك فوضى؟
\n\nتخيل أنك تبني منزلاً. لديك باب رئيسي (يمكن للجميع الدخول)، وغرفة نوم مقفلة (للعائلة فقط)، وخزنة في الجدار (لا يمكن الوصول إليها إلا أنت). في عالم البرمجة كائنية التوجه (OOP) بلغة PHP، تُسمى هذه "الأبواب" و"الأقفال" معدّلات الوصول.
\n\nإذا سبق لك كتابة كلاسات في PHP، فلا بد أنك صادفت الكلمات public و private و protected. ولكن ماذا تعني حقاً؟ لماذا لا نجعل كل شيء public ونعيش بسلام؟ الإجابة بسيطة: بدونها، سيتحول كودك إلى ساحة عامة، حيث يمكن لأي سكريبت أن يعطل منطق البرنامج عن طريق الخطأ.
في هذا المقال، سنشرح معدّلات الوصول في PHP بأمثلة واقعية، ونفهم الفرق بينها، ونتعلم كيفية استخدامها لبناء كود قوي ومرن. هذا الدليل مبني على سؤال شائع من Stack Overflow ومُعدّل لموقع pythonlib.ru التعليمي.
\n\nما هي معدّلات الوصول ولماذا نحتاجها؟
\n\nمعدّلات الوصول هي كلمات مفتاحية تحدد من أين يمكن الوصول إلى خصائص وطرق الكلاس. إنها أساس التغليف (Encapsulation)، أحد أركان OOP الأربعة. التغليف يخفي البنية الداخلية للكائن ويحمي البيانات من الاستخدام غير الصحيح.
\n\nفي PHP، هناك ثلاثة مستويات للوصول:
\n\n- \n
- Public — متاح للجميع (داخل الكلاس وخارجه). \n
- Private — متاح فقط داخل الكلاس نفسه. \n
- Protected — متاح داخل الكلاس وفي الكلاسات الوراثة (subclasses). \n
دعنا نشرح كل واحد منهم بأمثلة عملية.
\n\nPublic: "الدخول بدون استئذان"
\n\nمعدّل public هو الأكثر انفتاحاً. الخصائص والطرق المُعلنة كـ public يمكن قراءتها وتعديلها من أي مكان: من كلاس آخر، من سكريبت عام، من أي مكان.
<?php\nclass Car {\n public $brand = 'Toyota';\n\n public function honk() {\n return 'Beep!';\n }\n}\n\n$myCar = new Car();\necho $myCar->brand; // Toyota — يعمل\n$myCar->brand = 'Honda'; // نغير القيمة — يعمل\necho $myCar->honk(); // Beep!\n?>\n\nيبدو هذا مريحاً، أليس كذلك؟ لكن هناك مشكلة. تخيل أن كلاس User يحتوي على خاصية public $password. أي كود خارجي يمكنه قراءتها وتغييرها. هذه كارثة أمنية.
متى نستخدمه: للطرق التي تمثل واجهة API العامة للكلاس (مثل getUserName())، أو للثوابت.
Private: "خزنة لا يمكن اختراقها"
\n\nمعدّل private هو العكس التام لـ public. الخاصية أو الطريقة متاحة فقط داخل الكلاس الذي تم تعريفها فيه. حتى الكلاسات الوراثة لا ترى الأعضاء private من الكلاس الأب.
<?php\nclass BankAccount {\n private $balance = 1000;\n\n private function calculateInterest() {\n return $this->balance * 0.05;\n }\n\n public function getBalance() {\n return $this->balance;\n }\n\n public function applyInterest() {\n $this->balance += $this->calculateInterest();\n }\n}\n\n$account = new BankAccount();\n// echo $account->balance; // خطأ! لا يمكن الوصول لخاصية private\n// echo $account->calculateInterest(); // خطأ! لا يمكن الوصول لطريقة private\necho $account->getBalance(); // 1000 — يعمل لأن الطريقة public\n$account->applyInterest();\necho $account->getBalance(); // 1050\n?>\n\nفي هذا المثال، $balance و calculateInterest() مخفيان عن العالم الخارجي. نحن نتحكم في الرصيد فقط من خلال الطرق العامة getBalance() و applyInterest(). هذا هو التغليف (Encapsulation).