دوال Getters و Setters
جزء من قسم Object Oriented Programming في رحلة PHP على Coddy — الدرس 40 من 91.
الآن بعد أن فهمت معدلات الوصول (access modifiers)، كيف يمكنك التفاعل بأمان مع الخصائص الخاصة (private properties) من خارج الفئة (class)؟ الإجابة هي getters و setters - وهي دوال عامة (public methods) توفر وصولاً متحكماً فيه للبيانات الخاصة.
يقوم الـ getter باسترجاع قيمة الخاصية، بينما يقوم الـ setter بتعديلها. يتيح لك هذا النمط إضافة التحقق من الصحة أو المنطق عند الوصول إلى البيانات أو تغييرها:
<?php
class User {
private string $email;
private int $age;
public function getEmail(): string {
return $this->email;
}
public function setEmail(string $email): void {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->email = $email;
}
}
public function getAge(): int {
return $this->age;
}
public function setAge(int $age): void {
if ($age >= 0 && $age <= 150) {
$this->age = $age;
}
}
}
$user = new User();
$user->setEmail("john@example.com");
$user->setAge(25);
echo $user->getEmail() . "\n";
echo $user->getAge();
المخرجات:
john@example.com
25يقوم الـ setter بالتحقق من صحة تنسيق البريد الإلكتروني والتأكد من أن العمر منطقي قبل تخزين القيم. وبدون الـ setters، يمكن لأي شخص تعيين بيانات غير صالحة مباشرة. يمكنك أيضاً إنشاء خصائص للقراءة فقط من خلال توفير getter فقط، أو خصائص للكتابة فقط باستخدام setter فقط.
نقطة رئيسية: تمنحك دوال الجلب (Getters) ودوال التعيين (Setters) التحكم في كيفية الوصول إلى البيانات الخاصة وتعديلها، مما يسمح بالتحقق من الصحة، أو التنسيق، أو أي منطق مخصص.
التحدي
سهللنقم ببناء نظام مخزون منتجات يستخدم دوال الجلب (getters) ودوال التعيين (setters) لحماية بيانات المنتج والتحقق من صحتها. ستقوم بإنشاء فئة Product تضمن أن الأسعار موجبة دائماً وأن كميات المخزون ليست سالبة أبداً — مما يوضح كيف يمكن لدوال التعيين فرض قواعد العمل.
ستقوم بتنظيم الكود الخاص بك عبر ملفين:
Product.php— أنشئ فئةProductبثلاث خصائص خاصة (private):$name(سلسلة نصية)،$price(رقم عشري)، و$stock(عدد صحيح). قم بتنفيذ دوال الجلب والتعيين لكل خاصية مع قواعد التحقق التالية:- يجب أن تقبل
setName()السلاسل النصية غير الفارغة فقط — إذا كانت السلسلة فارغة بعد إزالة المسافات (trimming)، فلا تقم بتحديث الخاصية. - يجب أن تقبل
setPrice()القيم الأكبر من 0 فقط — ارفض الأسعار الصفرية أو السالبة. - يجب أن تقبل
setStock()القيم التي تساوي 0 أو أكبر — ارفض كميات المخزون السالبة.
getInfo()ترجع"[name]: $[price] ([stock] in stock)"مع تنسيق السعر إلى منزلتين عشريتين.- يجب أن تقبل
main.php— قم بتضمين ملف Product. ستتلقى أربعة مدخلات: اسم المنتج، السعر، كمية المخزون، وسعر جديد للتحديث. أنشئ كائناً (instance) منProductواستخدم دوال التعيين لتعيين الاسم الأولي، والسعر (محولاً إلى float)، والمخزون (محولاً إلى integer). اطبع نتيجةgetInfo(). ثم حاول تحديث السعر بقيمة السعر الجديد (محولاً إلى float) واطبعgetInfo()مرة أخرى. أخيراً، حاول تعيين المخزون إلى-5(قيمة غير صالحة) واطبعgetInfo()مرة أخيرة للتأكد من عدم تغيير المخزون.
تعمل دوال التعيين الخاصة بك كحراس — فهي تتحقق من صحة البيانات الواردة قبل السماح بإجراء تغييرات على الخصائص الخاصة. عندما يتم تمرير بيانات غير صالحة (مثل مخزون سالب)، تتجاهلها دالة التعيين ببساطة، مما يحافظ على القيمة الصالحة الموجودة. هذه هي قوة الكبسلة (encapsulation): يحافظ الكائن الخاص بك على سلامته بغض النظر عما يحاول الكود الخارجي فعله.
جرّب بنفسك
<?php
require_once 'Product.php';
// قراءة المدخلات
$name = trim(fgets(STDIN));
$price = trim(fgets(STDIN));
$stock = trim(fgets(STDIN));
$newPrice = trim(fgets(STDIN));
// TODO: إنشاء كائن (instance) جديد من Product
// TODO: استخدم دوال التعيين (setters) لتحديد name الأولي، و price (كـ float)، و stock (كـ integer)
// TODO: طباعة نتيجة getInfo()
// TODO: تحديث السعر بـ newPrice (كـ float) وطباعة getInfo() مرة أخرى
// TODO: محاولة تعيين stock إلى -5 (غير صالح) وطباعة getInfo() للتأكد من عدم تغيير المخزون
?>يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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)