__get, __set, __isset, __unset
جزء من قسم Object Oriented Programming في رحلة PHP على Coddy — الدرس 46 من 91.
يوفر PHP أربع طرق سحرية (magic methods) تعترض الوصول إلى الخصائص: __get()، و __set()، و __isset()، و __unset(). يتم استدعاء هذه الطرق عندما تحاول الوصول إلى خصائص غير موجودة أو غير قابلة للوصول.
يتم استدعاء الأسلوب __get() عند قراءة خاصية غير قابلة للوصول، بينما يتعامل __set() مع الكتابة إلى واحدة. يتيح لك ذلك إنشاء خصائص ديناميكية أو إضافة منطق عند الوصول إلى الخصائص:
<?php
class DynamicObject {
private array $data = [];
public function __get(string $name): mixed {
return $this->data[$name] ?? null;
}
public function __set(string $name, mixed $value): void {
$this->data[$name] = $value;
}
}
$obj = new DynamicObject();
$obj->title = "Hello";
$obj->count = 42;
echo $obj->title . " - " . $obj->count;
المخرجات:
Hello - 42يتم استدعاء الطريقة __isset() بواسطة isset() أو empty()، وتستجيب __unset() للدالة unset():
<?php
class DynamicObject {
private array $data = [];
public function __set(string $name, mixed $value): void {
$this->data[$name] = $value;
}
public function __isset(string $name): bool {
return isset($this->data[$name]);
}
public function __unset(string $name): void {
unset($this->data[$name]);
}
}
$obj = new DynamicObject();
$obj->name = "Test";
echo isset($obj->name) ? "exists" : "missing";
المخرجات:
existsتُستخدم هذه الطرق بشكل شائع لإنشاء حاويات بيانات مرنة، أو تنفيذ التحميل الكسول (lazy loading)، أو بناء كائنات تتصرف مثل المصفوفات مع الحفاظ على الهيكل كائني التوجه (object-oriented structure).
التحدي
سهللنقم ببناء مدير إعدادات مرن يقوم بتخزين الإعدادات ديناميكيًا باستخدام الطرق السحرية (magic methods). سيقوم صنفك (class) باعتراض الوصول إلى الخصائص لإدارة قيم الإعدادات، والتحقق من وجود الإعدادات، وإزالتها عند الحاجة — كل ذلك دون تحديد كل خاصية بشكل صريح.
ستقوم بتنظيم الكود الخاص بك عبر ملفين:
Config.php— أنشئ صنفConfigيستخدم مصفوفة خاصة (private array) لتخزين قيم الإعدادات داخليًا. قم بتنفيذ جميع الطرق السحرية الأربعة للخصائص:__get($name)— يعيد القيمة للمفتاح المعطى، أو"undefined"إذا كان المفتاح غير موجود__set($name, $value)— يخزن القيمة تحت المفتاح المعطى__isset($name)— يعيد ما إذا كان المفتاح موجودًا في الإعدادات__unset($name)— يزيل المفتاح من الإعدادات
count()تعيد عدد الإعدادات المخزنة.main.php— قم بتضمين ملف Config. ستتلقى ثلاثة مدخلات: اسم الإعداد، قيمة الإعداد، واسم إعداد ثانٍ. أنشئ كائنًا (instance) منConfigوقم بإجراء العمليات التالية:- قم بتعيين الإعداد الأول إلى القيمة المعطاة
- اطبع ما إذا كان الإعداد الأول موجودًا باستخدام
isset()— المخرج"exists"أو"missing" - اطبع قيمة الإعداد الأول
- اطبع العدد الحالي للإعدادات
- استخدم
unset()لإزالة الإعداد الأول - اطبع ما إذا كان الإعداد الأول موجودًا الآن — المخرج
"exists"أو"missing" - اطبع قيمة الإعداد الثاني (الذي لم يتم تعيينه مطلقًا)
يجب أن يكون كل مخرج في سطر مستقل. تتيح لك الطرق السحرية التفاعل مع كائن Config الخاص بك باستخدام صيغة الخصائص الطبيعية مثل $config->theme = "dark" و isset($config->theme)، على الرغم من عدم تعريف أي خصائص فعلية.
ورقة مرجعية
يوفر PHP أربع طرق سحرية (magic methods) لاعتراض الوصول إلى الخصائص:
__get(string $name): mixed— يتم استدعاؤها عند قراءة خاصية لا يمكن الوصول إليها__set(string $name, mixed $value): void— يتم استدعاؤها عند الكتابة في خاصية لا يمكن الوصول إليها__isset(string $name): bool— يتم تفعيلها بواسطةisset()أوempty()__unset(string $name): void— يتم تفعيلها بواسطةunset()
مثال على __get() و __set():
<?php
class DynamicObject {
private array $data = [];
public function __get(string $name): mixed {
return $this->data[$name] ?? null;
}
public function __set(string $name, mixed $value): void {
$this->data[$name] = $value;
}
}
$obj = new DynamicObject();
$obj->title = "Hello";
echo $obj->title; // Hello
مثال على __isset() و __unset():
<?php
class DynamicObject {
private array $data = [];
public function __set(string $name, mixed $value): void {
$this->data[$name] = $value;
}
public function __isset(string $name): bool {
return isset($this->data[$name]);
}
public function __unset(string $name): void {
unset($this->data[$name]);
}
}
$obj = new DynamicObject();
$obj->name = "Test";
echo isset($obj->name) ? "exists" : "missing"; // exists
تسمح هذه الطرق باستخدام الخصائص الديناميكية، والتحميل الكسول (lazy loading)، وحاويات البيانات المرنة مع الحفاظ على بنية البرمجة كائنية التوجه.
جرّب بنفسك
<?php
require_once 'Config.php';
// قراءة المدخلات
$settingName1 = trim(fgets(STDIN));
$settingValue = trim(fgets(STDIN));
$settingName2 = trim(fgets(STDIN));
// TODO: إنشاء مثيل (instance) من Config
// TODO: تعيين الإعداد الأول إلى القيمة المعطاة
// TODO: طباعة ما إذا كان الإعداد الأول موجوداً أم لا ("exists" أو "missing")
// TODO: طباعة قيمة الإعداد الأول
// TODO: طباعة العدد الحالي للإعدادات
// TODO: استخدام unset() لإزالة الإعداد الأول
// TODO: طباعة ما إذا كان الإعداد الأول موجوداً الآن ("exists" أو "missing")
// TODO: طباعة قيمة الإعداد الثاني (الذي لم يتم تعيينه مطلقاً)
?>يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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)