Punta de Choros

27 декември 2009

На 2009г й оставаха 120ч съществуване. От календара падна поредния лист с дата 27 декември и към 10.30ч сутринта ме събуди звън от телефона.

Инсталация на Microsoft шрифтове в Ubuntu 16.04

14 януари 2017

нсталация на Microsoft шрифтове в Ubuntu се поражда от идеята браузърите в различните системи, да показват еднакво текстовото съдържанието на интернет страниците.

Ubuntu 16.04 инсталация на USB disk on Key

19 ноември 2016

Арсеналът ми от мобилни компютри съдържа Fujitsu Lifebook AH530. Това е бюджетна машина от 2011г на Intel Core i5-480M процесор и 4GB DDR3 RAM памет.

gparted

Paragon ExtFS for Windows

30 юли 2016

ExtFS for Windows е утилита на Paragon Software разработена през 2013г. Тя представлява решение, предоставящо пълен достъп на четене и на запис до раздели ...

msvcr100.dll is missing Windows 10

04 октомври 2016

Майк Патерсън от Plixer, компания по компютърната сигурност, публикува доклад , че Windows 10 изпраща данни в криптиран вид от вашата машина на всеки пет минути. Той е направил максимума, за да спре изтичането, но системата продължавала да изпраща информация.

Клониране на обект в 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





до нови срещи   ^.^
29.09.2012 profruit 

0 Response to "Клониране на обект в PHP"

Публикуване на коментар

Този блог е реинкарнация на първите ми опити за споделяне в нета. На времето започнах с къси разкази на преживяното. После се обезсмисли и превърнах блога си в системно радио. Пиша единствено неща, които карат душата ми да живее: Ubuntu, WEB, Photoshop, Фотография, Споделено и т.н. Това е моето системно радио, разбирате ли? Моята вълна и вие сте на нея сега.

Архив на блога