Клониране на обект в PHP
PHP4$obj1 = $obj2; //copy - клониране на обекта
$obj1 = &$obj2; //link - един и същи обект под различно име
PHP5
$obj1 = clone $obj2; //copy - клониране на обекта
$obj1 = $obj2; //link - един и същи обект под различно име
Въведение
PHP4 не предлага никаква възможност за копиране на обектите, освен стандартния. Той е бит по бит - 1:1 на всички свойства на обекта.В PHP4 копиране на обекта става много просто. Достатъчно е да се присвои значението на една обектна променлива към нова такава.
Пример:
<?php class Originale { //PHP4 } $first = new Originale; $second = $first;Променливите $second и $first указват на два различни обекта.
Практиката показала непрактичност при такъв подход. Например, обект, представляващ съединение с база данни или обекти, чийто свойства са обекти, а още обекти, изграждащи дървовидни структури. Това накарало разработчиците, да въведат в PHP5 ключова дума clone.
Пример:
<?php class Originale { //PHP5 } $first = new Originale; $second = clone $first;Променливите $second и $first указват на два различни обекта.
Когато копие на обекта се прави с clone в PHP5, PHP автоматически проверява за наличие на магически метод __clone. Липсата му ще накара PHP, да създаде обикновено копие на обекта. Ако магическия метод е определен, то PHP ще го изпълни едва след като копира всички свойства от оригинала.
PHP версия от командна линия
За прозрачност на темата, нека узнаем версия PHP на разположение чрез терминала. Въвеждаме просто php -v.profruit@prodesktop:~$ php -v
PHP 5.3.2-1ubuntu4.18 with Suhosin-Patch (cli)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
От теория към практика
С поредица от примери нека видим как работят нещата.clone.class.php
<?php class original { public $var; }object.php
<?php include('clone.class.php'); $first = new original; $first->var = 1; $second = $first; echo $first->var, '<br>'; //1 echo $second->var; //1Нека разместим нещата и погледнем отново на резултата.
<?php include('clone.class.php'); $first = new original; $first->var = 1; $second = $first; $second->var = 2; echo $first->var, '<br>'; //2 echo $second->var; //2Имаме един и същи обект под различно име. Изменението в коя да е инстанция рефлектира на другата по същия начин. Напомням, че сме под PHP 5.3.2.
Дойде ред на същинско клониране
<?php include('clone.class.php'); $first = new original; $first->var = 1; $second = clone $first; echo $second->var, '<br>'; //1 $second->var = 2; echo $first->var, '<br>'; //1 echo $second->var; //2Клонирането на обект originale води до създаване на ново копие. Всички свойства с техните значения са преминали в клонирания обект. Особеност при клониране на обекта е, че конструктора не се извиква, в което убеждава поредния пример.
<?php class Originale { public $var; function __construct() { $this->var = __CLASS__; echo 'конструктор на клас '. $this->var; } } $first = new Originale; $second = clone $first;Резултатът от изпълнението печати в браузъра само веднъж конструктор на клас Originale.
Това говори, че конструктора е извикан само от създаването на обект new Originale, независимо, че е създаден нов обект $second. Разрешението на подобна нужда, разработчиците предлагат магически метод __clone().
__clone() носи идеята на __construct()
Метод __clone() не приема параметър. Ако такъв е описан PHP автоматически го
привежда в действие и само за клонинга. Пример:
<?php class Originale { public $var; function __construct() { $this->var = __CLASS__; echo "конструктор на клас {$this->var} <br>"; } function __clone() { echo 'обектът клониран от '. $this->var; } } $first = new Originale; $second = clone $first;Резултатът от изпълнението печати в браузъра следните два реда:
конструктор на клас Originale
обектът клониран от Originale
Става ясно, че това което прави конструктора при създаване на обект е по силите на магически метод __clone в момента на клониране.
И поредна особеност. Ако ви засърбят ръцете, да извикате конструктора по този начин:
$first = new Originale;
echo $first->__construct();
Може и ще работи, но ще се приеме за моветон.
Това обаче не работи:
echo $second->__clone();
PHP ще възнегодува с следното съобщение:
Fatal error: Cannot call __clone() method on objects
до нови срещи ^.^
0 Response to "Клониране на обект в PHP"
Публикуване на коментар