في هذا الدرس 6تصفّح المواضيع
يتيح الصنف المجهول (new class { ... }) تعريف وإنشاء كائن فوري للاستخدام لمرة واحدة في نفس السطر دون الحاجة لإنشاء ملف أو اسم صنف منفصل.
- مرّر معاملات البناء مباشرة بعد الكلمة
new class($arg1, $arg2) { ... }تماماً مثل إنشاء كائن من صنف عادي. - يمكن للصنف المجهول أن يحتوي على خصائص محددة النوع وثوابت ودالة بناء ودوال عامة أو خاصة.
- استخدم الأصناف المجهولة للمساعدات المحلية السريعة أو الكائنات المؤقتة داخل الاختبارات.
يمرر التعبير new class("CheckoutJob") النص إلى دالة البناء الداخلية ويُرجع فوراً كائناً جاهزاً للاستخدام.
<?php
$timer = new class("CheckoutJob") {
public function __construct(public string $label) {}
public function summary(int $ms): string {
return "[{$this->label}] finished in {$ms}ms";
}
};
echo $timer->summary(42) . "\n";
يمكن للصنف المجهول أن يرث من صنف أب عبر extends ويطبق واجهة أو أكثر عبر implements، مما يجعله مثالياً لبناء بدائل الاختبار السريعة (Mocks / Fakes).
- اكتب
new class implements MailerInterface { ... }لتلبية متطلبات أي واجهة برمجية بشكل فوري. - بما أن الكائن المجهول يطبق الواجهة، فإن الفحص
$anon instanceof MailerInterfaceيُرجعtrue. - يتيح هذا النمط اختبار الخدمات في الذاكرة دون إرسال رسائل حقيقية أو الاتصال ببوابات دفع خارجية.
يطبق الصنف المجهول الواجهة AuditLogger ويحفظ الأحداث المسجلة في مصفوفة داخل الذاكرة للتحقق الفوري منها.
<?php
interface AuditLogger { public function record(string $event): void; }
$memoryLog = new class implements AuditLogger {
public array $entries = [];
public function record(string $event): void { $this->entries[] = $event; }
};
$memoryLog->record("user.login");
$memoryLog->record("order.paid");
echo implode(" -> ", $memoryLog->entries) . "\n";
على عكس json_encode() التي تفقد اسم صنف الكائن وخصائصه الخاصة، تحوّل الدالة serialize() الكائن إلى نص قابل للتخزين يحتفظ بنوع الصنف وحالة خصائصه كاملة.
- ترمّز الدالة
serialize($object)اسم الصنف وجميع الخصائص العامة والمحمية والخاصة في سلسلة نصية مهيكلة. - تعيد الدالة
unserialize($payload)بناء الكائن الحي بنفس حالته دون إعادة استدعاء__construct(). - تُستخدم هذه الآلية بكثرة لتخزين كائنات المهام الخلفية (Queued Jobs) في Redis أو قاعدة البيانات.
تحفظ serialize() كلاً من الخاصية العامة $task والخاصة $retries، وتستعيد unserialize() الكائن QueuedJob بالكامل.
<?php
class QueuedJob {
public function __construct(public string $task, private int $retries) {}
public function info(): string { return "{$this->task} (tries={$this->retries})"; }
}
$raw = serialize(new QueuedJob("SendInvoicePdf", 3));
$restored = unserialize($raw);
echo $restored->info() . "\n";
يوفر PHP 8 الدالتين السحريتين __serialize(): array و__unserialize(array $data): void للتحكم الدقيق في البيانات التي يتم حفظها واستعادتها.
- تُرجع الدالة
__serialize(): arrayمصفوفة ترابطية نظيفة تمثل حالة الكائن المراد حفظها (مع استبعاد المقابض الحية أو المفاتيح المؤقتة). - تستقبل الدالة
__unserialize(array $data): voidتلك المصفوفة الترابطية عند فك التسلسل لتعيد تعبئة خصائص الكائن. - فضّل دائماً الثنائي الحديث
__serialize()و__unserialize()على الدالتين القديمتين__sleep()و__wakeup().
تستبعد __serialize() الخاصية المؤقتة $tempCache عند الحفظ، وتعيد __unserialize() تهيئتها بالقيمة "rebuilt".
<?php
class SessionToken {
public function __construct(public string $user, private string $tempCache = "skip") {}
public function __serialize(): array { return ["user" => $this->user]; }
public function __unserialize(array $data): void {
$this->user = $data["user"];
$this->tempCache = "rebuilt";
}
public function status(): string { return "{$this->user}:{$this->tempCache}"; }
}
$tok = unserialize(serialize(new SessionToken("admin")));
echo $tok->status() . "\n";
لا تمرر أبداً بيانات خارجية غير موثوقة إلى unserialize() دون تقييد الخيار allowed_classes، لمنع ثغرات حقن الكائنات (PHP Object Injection).
- مرّر الخيار
['allowed_classes' => [SafeDto::class]]كمعامل ثانٍ للدالةunserialize()لحصر فك التسلسل في الأصناف المسموحة فقط. - مرّر
['allowed_classes' => false]لمنع إنشاء أي كائنات إطلاقاً، فيتحول أي كائن غير مصرح به إلى__PHP_Incomplete_Classغير قابل للتنفيذ. - عند تبادل البيانات مع المتصفح أو الكوكيز أو واجهات API الخارجية، استخدم
json_encode()وjson_decode()بدلاً منserialize().
لأن الصنف DangerExec غير موجود في القائمة البيضاء allowed_classes، يرفض PHP إنشاءه ويحوله إلى __PHP_Incomplete_Class آمن.
<?php
class SafeCart { public string $sku = "KB-90"; }
class DangerExec { public string $cmd = "rm"; }
$payload = serialize(new DangerExec());
$res = unserialize($payload, ["allowed_classes" => [SafeCart::class]]);
echo get_debug_type($res) . "\n";
يوفر PHP المعامل instanceof ودوال فحص سريعة للتحقق من صنف الكائن وسلسلة وراثته والواجهات التي يطبقها وقت التشغيل.
- يُرجع التعبير
$obj instanceof TargetTypeالقيمةtrueإذا كان الكائن من نفس الصنف أو يرث منه أو يطبق تلك الواجهة. - استخدم
get_debug_type($val)(في PHP 8.0+) أو$obj::classلمعرفة اسم الصنف الفعلي للكائن وقت التشغيل. - استخدم
method_exists($obj, 'name')وproperty_exists($obj, 'prop')لفحص وجود الدوال والخصائص برمجياً.
يتحقق الكود من تطبيق الواجهة عبر instanceof، ويقرأ اسم الصنف عبر $rep::class، ويؤكد وجود الدالة toCsv().
| الأداة / الدالة | الوظيفة الأساسية | مثال |
|---|---|---|
$obj instanceof Type | Checks class, parent class, or interface match | $r instanceof Exportable |
$obj::class | Returns exact class name string (PHP 8.0+) | "SalesReport" |
method_exists($o, $m) | Checks if method is defined on object/class | method_exists($r, "toCsv") |
unserialize($s, $opts) | Restores object with class whitelist | ["allowed_classes" => [Safe::class]] |
<?php
interface Exportable { public function toCsv(): string; }
class SalesReport implements Exportable {
public function toCsv(): string { return "id,total"; }
}
$rep = new SalesReport();
echo ($rep instanceof Exportable ? "Exportable" : "No") . " | ";
echo $rep::class . " | ";
echo (method_exists($rep, "toCsv") ? "has toCsv()" : "missing") . "\n";
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
يوفر PHP المعامل instanceof ودوال فحص سريعة للتحقق من صنف الكائن وسلسلة وراثته والواجهات التي يطبقها وقت التشغيل. يُرجع التعبير $obj instanceof TargetType القيمة true إذا كان الكائن من نفس الصنف أو يرث منه أو يطبق تلك الواجهة. استخدم get_debug_type($val) (في PHP 8.0+) أو $obj::class لمعرفة اسم الصنف الفعلي للكائن وقت التشغيل. استخدم method_exists($obj, 'name') وproperty_exists($obj, 'prop') لفحص وجود الدوال والخصائص برمجياً.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 Anonymous & Serialize الأصناف المجهولة والتسلسل
- أنشئ كائنات فورية عبر new class، وخزّن الكائنات بأمان عبر __serialize و__unserialize، وافحص الأصناف والدوال في وقت التشغيل.
- للمراجعة
- 02 Creating Inline Objects with new class إنشاء الكائنات الفورية بالأصناف المجهولة new class
- المفهوم الأساسي لقسم إنشاء الكائنات الفورية بالأصناف المجهولة new class في لغة PHP الحديثة.
- للمراجعة
- 03 Implementing Interfaces in Anonymous Classes تطبيق الواجهات داخل الأصناف المجهولة للاختبار السريع
- الصياغة البرمجية والتطبيق العملي المباشر لقسم تطبيق الواجهات داخل الأصناف المجهولة للاختبار السريع.
- للمراجعة
- 04 Serializing Objects with serialize تحويل الكائنات إلى نص قابل للتخزين بـ serialize
- قواعد التحقق وأفضل الممارسات القياسية الخاصة بقسم تحويل الكائنات إلى نص قابل للتخزين بـ serialize.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 PHP PHP
- PHP: Hypertext Preprocessor
- لغة البرمجة النصية على جانب الخادم لبناء تطبيقات الويب الديناميكية وواجهات البرمجة.
- للمراجعة
- 02 CLI CLI
- Command-Line Interface
- واجهة سطر الأوامر التي تتيح تشغيل ملفات PHP مباشرة عبر الطرفية.
- للمراجعة
- 03 FPM FPM
- FastCGI Process Manager
- مدير عمليات FastCGI عالي الأداء لمعالجة طلبات خادم الويب في PHP.
- للمراجعة
- 04 HTML HTML
- HyperText Markup Language
- لغة الترميز القياسية التي يولدها محرك PHP ويرسلها إلى متصفح العميل بعد التنفيذ.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
أنشئ ملف PHP محلياً ونفّذ المثال البرمجي المشروح في قسم إنشاء الكائنات الفورية بالأصناف المجهولة new class للتحقق من المخرجات.
-
بدّل بين الحالات الثلاث في المحاكي التفاعلي ضمن قسم تطبيق الواجهات داخل الأصناف المجهولة للاختبار السريع وقارن مخرجات التنفيذ.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي8 أسئلة تنتظرك +
كيف تنشئ كائناً فورياً من صنف مجهول في PHP مع تمرير القيمة "v1" إلى دالة البناء الخاصة به؟
توضع معاملات البناء بين قوسين مباشرة بعد الكلمة new class(...).
هل يمكن للصنف المجهول في PHP أن يطبق واجهة (implements) أو يرث من صنف أب (extends)؟
تدعم الأصناف المجهولة كلاً من extends وimplements تماماً كالأصناف المسماة.
ما زوج الدوال السحرية الحديث في PHP 8 المخصص للتحكم في كيفية تسلسل الكائن وفك تسلسله؟
هما الدالتان القياسيتان الحديثتان في PHP 8 لتخصيص تسلسل الكائنات.
كيف تمنع ثغرات حقن الكائنات عند استدعاء unserialize() على نص يفترض أن يحتوي فقط على كائنات من الصنف OrderDto؟
يحدد الخيار allowed_classes قائمة بيضاء بالأصناف المسموح بإنشائها فقط.
ماذا تنتج الدالة unserialize($payload, ["allowed_classes" => false]) إذا كان النص يحتوي على كائن متسلسل؟
ضبط allowed_classes على false يمنع إنشاء أي صنف ويحول الكائنات إلى __PHP_Incomplete_Class آمن.
متى تُرجع العبارة ($obj instanceof Auditable) القيمة المنطقية true؟
يفحص المعامل instanceof الصنف المباشر وجميع الأصناف الأب والواجهات المطبقة.
في PHP 8.0+، كيف يمكنك الحصول على اسم الصنف الفعلي للكائن $service وقت التشغيل باستخدام صيغة ::class؟
يدعم PHP 8.0+ كتابة $object::class مباشرة على الكائن لإرجاع اسم صنفه النصي.
ما الدالة المدمجة في PHP التي تفحص ما إذا كان الكائن $plugin يحتوي على دالة معرفة باسم "boot"؟
تُرجع method_exists($plugin, "boot") القيمة true إذا كانت الدالة موجودة في الكائن.