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

__clone واستنساخ الكائنات

جزء من قسم البرمجة كائنية التوجه في رحلة PHP على Coddy. الدرس 48 من 91.

عندما تُسنِد كائنًا إلى متغير آخر في PHP، فإنك لا تُنشئ نسخة — فكلا المتغيرين يشيران إلى الكائن نفسه. ولإنشاء نسخة مستقلة فعلية، تحتاج إلى استخدام الكلمة المفتاحية clone:

<?php
class Product {
    public function __construct(
        public string $name,
        public float $price
    ) {}
}

$original = new Product("Laptop", 999.99);
$copy = clone $original;

$copy->price = 899.99;
echo $original->price . " - " . $copy->price;

الناتج:

999.99 - 899.99

بشكل افتراضي، تنفّذ PHP نسخًا سطحيًا - إذ تنسخ جميع قيم الخصائص مباشرةً. يعمل هذا بشكل جيد مع القيم العددية، لكن الكائنات الموجودة داخل كائنك تظل تشير إلى المثيل نفسه. يتيح لك __clone() magic method تخصيص هذا السلوك:

<?php
class Order {
    public function __construct(
        public int $id,
        public array $items = []
    ) {}
    
    public function __clone(): void {
        $this->id = 0;
        $this->items = [];
    }
}

$order1 = new Order(101, ["Book", "Pen"]);
$order2 = clone $order1;

echo "Original: " . $order1->id . ", Clone: " . $order2->id;

المخرجات:

Original: 101, Clone: 0

يتم استدعاء الطريقة __clone() على الكائن الجديد بعد إنشاء النسخة السطحية. هنا يمكنك إعادة تعيين المعرّفات، وإنشاء نسخ جديدة من الكائنات المتداخلة، أو إجراء أي تنظيف مطلوب لكي يكون clone مستقلًا تمامًا.

challenge icon

التحدي

سهل

لنُنشئ نظامًا لإصدارات المستندات يوضّح كيف يؤدي الاستنساخ إلى إنشاء نسخ مستقلة، وكيف تتيح لك الطريقة السحرية __clone() تخصيص ما يحدث عند استنساخ كائن.

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

  • Document.php: أنشئ فئة Document تمثّل مستندًا ذا إصدارات. استخدم ترقية المُنشئ لتعريف $title عامًا (من النوع string)، و$content عامًا (من النوع string)، و$version عامًا (من النوع integer، وقيمته الافتراضية 1). أضف خاصية $createdAt خاصة تخزّن الطابع الزمني الحالي (استخدم date('Y-m-d H:i:s') في المُنشئ). يحتاج مستندك إلى:
    • getCreatedAt(): تُرجع الطابع الزمني للإنشاء
    • __clone(): عند استنساخ مستند، يجب زيادة الإصدار بمقدار 1، كما يجب إعادة تعيين $createdAt إلى الطابع الزمني الحالي (فالنسخة المستنسخة هي إصدار جديد تم إنشاؤه "now")
  • main.php: أدرج ملف Document. ستتلقى ثلاث مدخلات: عنوانًا، ومحتوى، ونص محتوى جديدًا للإصدار المستنسخ. أنشئ Document باستخدام العنوان والمحتوى. ثم استنسخه لإنشاء إصدار جديد، وحدّث محتوى النسخة المستنسخة إلى نص المحتوى الجديد. اطبع أربعة أسطر:
    • إصدار المستند الأصلي
    • إصدار المستند المستنسخ
    • محتوى المستند الأصلي
    • محتوى المستند المستنسخ

يوضّح هذا النظام كيف تتيح لك __clone() التحكم فيما يحدث أثناء الاستنساخ. يحتفظ المستند الأصلي بإصداره ووقت إنشائه، بينما تصبح النسخة المستنسخة تلقائيًا إصدارًا جديدًا بطابع زمني حديث، وهو أمر مثالي لتتبّع سجل المستندات حيث تمثّل كل نسخة مستنسخة مراجعة جديدة.

جرّب بنفسك

<?php

require_once 'Document.php';

// اقرأ المدخلات
$title = trim(fgets(STDIN));
$content = trim(fgets(STDIN));
$newContent = trim(fgets(STDIN));

// TODO: أنشئ Document بالعنوان والمحتوى

// TODO: استنسخ المستند لإنشاء إصدار جديد

// TODO: حدّث محتوى النسخة إلى سلسلة المحتوى الجديدة

// TODO: اطبع أربعة أسطر:
// 1. إصدار المستند الأصلي
// 2. إصدار المستند المستنسخ
// 3. محتوى المستند الأصلي
// 4. محتوى المستند المستنسخ

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

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

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

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