Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

__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.

challenge icon

التحدي

سهل

لنَبْنِ نظامًا لتخزين ملف تعريف المستخدم مؤقتًا يوضّح كيف تمنحك __serialize() و__unserialize() التحكم في البيانات التي يتم حفظها وكيفية استعادتها.

ستنظّم الشيفرة عبر ملفين:

  • UserProfile.php: أنشئ فئة UserProfile تمثّل ملف تعريف المستخدم مع إمكانات التخزين المؤقت. استخدم ترقية constructor لتعريف private properties لـ $userId (string) و$username (string) و$email (string) و$accessToken (string). أضف private $cachedAt property تخزّن وقت تخزين الملف الشخصي مؤقتًا (اضبطها على "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"
// اعتمادًا على ما إذا كان رمز الملف الشخصي المستعاد يطابق الأصلي

?>
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم PHP عبر الإنترنت