2015-06-15 7 views
1

Для проекта измерения у меня есть класс MeterReadings, с конструктором, который берет предыдущее чтение как основу для всех его значений свойств, кроме метки времени. В примере объект имеет только 3 свойства, в реальной жизни их гораздо больше. Я мог бы прокладывать линию по каждому свойству X doКак создать новый экземпляр, копирующий значения из другого объекта PHP

$this->propertyX=$prevMS->propertyX 

но это быстро становится утомительным.

Какова наилучшая практика для копирования всех значений свойств из объекта $prevMS?

<?php class MeterReadings{ 
    function __construct($prevMS=NULL){ 
     if($prevMS===NULL){ 
      $this->gas=0; 
      $this->water=0; 
      $this->electricity=0; 
     }else{ 
      //PHP can duplicate an object by assignment, 
      //so I expected to be able to create a copy of $prevMS 
      //but cannot $this=$prevMS; 
      //and cannot $this= clone $that; 
      //which both throw error 'Cannot re-assign $this' 
      foreach($prevMS as $key => $value){ 
      //logs "Undefined property: MeterReadings::$0" 
      print "$key => $value\n"; 
      $this->$key = $prevMS->$value; 
      } 
     } 
     $this->date=time();//set timestamp for this object 
    } 
} 
$test= new MeterReadings(); 
$test2 = new MeterReadings($test); 
print_r($test); 
print_r($test2); 
?>gets me 

gas => 0 
water => 0 
electricity => 0 
date => 1434448706 
MeterReadings Object 
(
    [gas] => 0 
    [water] => 0 
    [electricity] => 0 
    [date] => 1434448706 
) 
MeterReadings Object 
(
    [gas] => 
    [water] => 
    [electricity] => 
    [date] => 1434448706 
) 

ответ

2

Вы можете использовать clone и __cloneMagic Method управлять тем, что получить это клонированы.

Например:

class Test 
{ 
    public $value1; 
    public $value2; 
    public $timestamp; 

    public function __clone() 
    { 
     $this->timestamp = null; 
    } 
} 

$test = new Test(); 
$test->value1 = 1; 
$test->value2 = 2; 
$test->timestamp = time(); 

$test2 = clone $test; 

print_r($test2); 

// Test Object 
// (
//  [value1] => 1 
//  [value2] => 2 
//  [timestamp] => 
//) 

Альтернатива:

Чтобы сохранить вещи, как в __constuct, как указано комментарий ниже:

class Test 
{ 
    public $value1; 
    public $value2; 
    public $timestamp; 

    public function __construct (Test $copy = null) 
    { 
     if($copy) { 
      foreach ($copy as $key => $value) { 
       $this->$key = $value; 
      } 
     } 
     $this->timestamp = 'whoop'; 
    } 
} 

$test = new Test(); 
$test->value1 = 1; 
$test->value2 = 2; 
$test->timestamp = 'whatev\'s'; 

$test2 = new Test($test); 

print_r($test2); 

// Test Object 
// (
//  [value1] => 1 
//  [value2] => 2 
//  [timestamp] => 'whoop' 
//) 

Это будет работать для объектов, которые не итерации и для свойств, которые защищены (но не приват е). Для объектов, которые можно исправить и вернуть что-то еще, вы можете использовать get_object_vars(), documentation here. Для вещей, которые являются частными (вы уверены, что вам нужны частные, это необычно), вам нужно будет создать геттеры. Они могут быть защищены, если вы не хотите, чтобы они были доступны снаружи.

+0

DanielM, спасибо за URL-адрес Magic Method. Я пытаюсь сохранить все в методе __construct, но '$ this = clone ($ prevMS);' не разрешено. Надеемся, что все ценности будут закрыты для класса. Я приспосабливаю этот вопрос к этой цели. – user1789266

+0

Объекты в PHP хранятся в качестве ссылок. Даже если вы _could_ выполните '$ this = $ object', вам придется ссылаться на один и тот же объект. В качестве альтернативы вы можете сделать 'foreach ($ object as $ key => $ value) {$ this -> $ key = $ value; } '. Для этого объект не должен быть итерируемым. Если объект _is_ itterable, то вы можете использовать 'get_object_vars()' – DanielM

+0

Спасибо. Мы одновременно редактировали вопросы и ответы. Я вижу свою ошибку; shoudln't ссылается только на '$ prevMS -> $ value', а на' $ value'. – user1789266

Смежные вопросы