استنساخ الكائنات في PHP
ليس من المحبّذ في كثير من الأحيان إنشاء نسخة طبق الأصل للكائن، وأفضل مثال على ذلك هو الحاجة لنسخ من التوابع البانية وذلك عند وجود كائن يمثل نافذة GTK ويحمل مصادر هذه النافذة، وعند إنشاء نسخة ثانية فإنّك قد ترغب في إنشاء نافذة جديدة تمتلك نفس الخصائص وأن يحمل الكائن الجديد الخصائص التابعة للنافذة الجديدة. من الأمثلة الأخرى أيضًا هو أن يحمل الكائن الذي تستخدمه مرجعًا إلى كائن آخر يستخدمه وعندما ترغب في إنشاء نسخة طبق الأصل للكائن الأب فستحتاج إلى إنشاء نسخة جديدة من الكائن الآخر بحيث تكون النسخة المطابقة للأصل مفصولة عنه.
يمكن إنشاء نسخة من الكائن باستخدام الكلمة المفتاحية clone
(والتي تستدعي التابع __clone()
عندما يكون ذلك ممكنًا)، ولا يمكن استدعاء التابع __clone()
بصورة مباشرة.
$copy_of_object = clone $object;
عند إنشاء نسخة من الكائن، تصنع PHP 5 نسخة عميقة من جميع خصائص الكائن، وأيّ خاصيات تكون مراجع لمتغيرات أخرى ستبقى كمراجع.
void __clone ( void )
عند اكتمال عملية الاستنساخ وفي حال تعريف التابع __clone()
، يُستدعى التابع __clone()
الخاص بالكائن الجديد للسماح بتعديل الخاصيات التي تكون بحاجة إلى تعديل.
المثال 1: استنساخ كائن
<?php
class SubObject
{
static $instances = 0;
public $instance;
public function __construct() {
$this->instance = ++self::$instances;
}
public function __clone() {
$this->instance = ++self::$instances;
}
}
class MyCloneable
{
public $object1;
public $object2;
function __clone()
{
// Force a copy of this->object, otherwise
// it will point to same object.
$this->object1 = clone $this->object1;
}
}
$obj = new MyCloneable();
$obj->object1 = new SubObject();
$obj->object2 = new SubObject();
$obj2 = clone $obj;
print("Original Object:\n");
print_r($obj);
print("Cloned Object:\n");
print_r($obj2);
?>
يعطي المثال السابق المخرجات التالية:
Original Object:
MyCloneable Object
(
[object1] => SubObject Object
(
[instance] => 1
)
[object2] => SubObject Object
(
[instance] => 2
)
)
Cloned Object:
MyCloneable Object
(
[object1] => SubObject Object
(
[instance] => 3
)
[object2] => SubObject Object
(
[instance] => 2
)
)
قدّم الإصدار 7.0.0 من PHP إمكانية الوصول إلى أحد أعضاء الكائن المُستنسخ للتو بواسطة تعبير واحد.
المثال 2: الوصول إلى أحد أعضاء كائن مستنسخ للتو
<?php
$dateTime = new DateTime();
echo (clone $dateTime)->format('Y');
?>
يعطي المثال السابق مخرجات مشابهة لما يلي:
2016