__serialize و __unserialize
جزء من قسم البرمجة كائنية التوجه في رحلة PHP على Coddy. الدرس 49 من 91.
عندما تحتاج إلى تحويل كائن إلى سلسلة نصية لتخزينها أو نقلها، تستخدم PHP التسلسل. تمنحك الطريقتان السحريتان __serialize() و__unserialize() التحكم في البيانات التي يتم حفظها بالضبط وكيفية استعادتها.
تعيد طريقة __serialize() مصفوفة من data ليتم إجراء التسلسل عليها، بينما تستقبل __unserialize() تلك المصفوفة وتعيد بناء الكائن:
<?php
class Session {
public function __construct(
private string $userId,
private array $data,
private int $createdAt
) {}
public function __serialize(): array {
return [
'userId' => $this->userId,
'data' => $this->data
];
}
public function __unserialize(array $data): void {
$this->userId = $data['userId'];
$this->data = $data['data'];
$this->createdAt = time();
}
public function getCreatedAt(): int {
return $this->createdAt;
}
}
$session = new Session("user123", ["theme" => "dark"], time());
$serialized = serialize($session);
$restored = unserialize($serialized);
echo "Created at: " . $restored->getCreatedAt();
لاحظ كيف يتم استبعاد createdAt من التسلسل، ويحصل على طابع زمني جديد عند إلغاء التسلسل. وهذا مفيد لاستبعاد البيانات الحساسة أو القيم المؤقتة أو الموارد التي لا يمكن إجراء تسلسل لها، مثل اتصالات قاعدة البيانات.
استبدلت هذه الأساليب الأساليب الأقدم __sleep() و__wakeup() في PHP 7.4، مما يوفر نهجًا أكثر وضوحًا تعمل فيه مباشرةً مع مصفوفات data بدلًا من أسماء property.
التحدي
سهللنَبْنِ نظامًا لتخزين ملف تعريف المستخدم مؤقتًا يوضّح كيف تمنحك __serialize() و__unserialize() التحكم في البيانات التي يتم حفظها وكيفية استعادتها.
ستنظّم الشيفرة عبر ملفين:
UserProfile.php: أنشئ فئةUserProfileتمثّل ملف تعريف المستخدم مع إمكانات التخزين المؤقت. استخدم ترقية constructor لتعريف private properties لـ$userId(string) و$username(string) و$email(string) و$accessToken(string). أضف private$cachedAtproperty تخزّن وقت تخزين الملف الشخصي مؤقتًا (اضبطها على"not cached"initially في constructor). يجب أن تتضمن فئتك ما يلي:__serialize(): تُرجع array تحتوي فقط علىuserIdوusernameوemail. إنaccessTokenحساس، ولذلك يجب ألا تتم عملية تسلسله مطلقًا. ستتم إعادة إنشاء الطابع الزمنيcachedAtعند الاستعادة.__unserialize(): تستعيدuserIdوusernameوemailمن data array. تضبطaccessTokenعلى"expired"(لأن الرموز المميّزة لا ينبغي أن تستمر).getInfo(): تُرجع string بالتنسيق:"[username] ([email]) - Token: [accessToken] - Cached: [cachedAt]"
main.php: أدرج ملف UserProfile. ستتلقى أربع مدخلات: معرّف مستخدم، واسم مستخدم، وبريدًا إلكترونيًا، وaccess token. أنشئ instance منUserProfileبهذه القيم. اطبع ثلاثة أسطر:- معلومات ملف التعريف الأصلي (before serialization)
- نفّذ Serialize لملف التعريف باستخدام
serialize()، ثم نفّذ unserialize باستخدامunserialize()لإنشاء ملف تعريف مستعاد. اطبع معلومات ملف التعريف المستعاد. - اطبع
"Token preserved: yes"أو"Token preserved: no"اعتمادًا على ما إذا كان token الخاص بملف التعريف المستعاد يطابق الأصلي (تلميح: ينبغي ألا يتطابقا لأن الرموز المميّزة تنتهي صلاحيتها عند الاستعادة)
هذا النمط أساسي لتخزين بيانات المستخدم بأمان. تريد تخزين معلومات ملف التعريف، لكن لا تريد أبدًا الاحتفاظ ببيانات اعتماد حساسة مثل access tokens. عند استعادة الملف الشخصي من ذاكرة التخزين المؤقت، يتم وضع علامة على token باعتباره منتهي الصلاحية، مما يجبر التطبيق على الحصول على token جديد.
جرّب بنفسك
<?php
require_once 'UserProfile.php';
// اقرأ المدخلات
$userId = trim(fgets(STDIN));
$username = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$accessToken = trim(fgets(STDIN));
// TODO: أنشئ كائن UserProfile بالقيم المدخلة
// TODO: اطبع معلومات الملف الشخصي الأصلي (قبل التسلسل)
// TODO: سلسِل الملف الشخصي، ثم ألغِ تسلسله لإنشاء ملف شخصي مستعاد
// TODO: اطبع معلومات الملف الشخصي المستعاد
// TODO: Print "Token preserved: yes" or "Token preserved: no"
// اعتمادًا على ما إذا كان رمز الملف الشخصي المستعاد يطابق الأصلي
?>يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
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)تدرّب بنفسك: مترجم PHP عبر الإنترنت