Вопрос

Похоже, что в PHP объекты передаются по ссылке. Даже операторы присваивания не создают копию объекта.

Вот простое, надуманное доказательство:

<?php

class A {
    public $b;
}


function set_b($obj) { $obj->b = "after"; }

$a = new A();
$a->b = "before";
$c = $a; //i would especially expect this to create a copy.

set_b($a);

print $a->b; //i would expect this to show 'before'
print $c->b; //i would ESPECIALLY expect this to show 'before'

?>

В обоих случаях печати я получаю «после»

Итак, как мне передать $ a в set_b () по значению, а не по ссылке?

Это было полезно?

Решение

В PHP 5+ объекты передаются по ссылке. В PHP 4 они передаются по значению (поэтому во время выполнения он передавался по ссылке, что устарело).

Вы можете использовать оператор 'clone' в PHP5 для копирования объектов:

$objectB = clone $objectA;

Кроме того, это просто объекты, которые передаются по ссылке, а не все, как вы сказали в своем вопросе ...

Другие советы

Ответы обычно можно найти в книгах по Java.

<Ол>
  • Клонирование: Если вы не переопределяете метод клонирования, по умолчанию используется мелкая копия. Если ваши объекты имеют только примитивные переменные-члены, это нормально. Но в языке без типов с другим объектом в качестве переменных-членов это головная боль.

  • <Литий> <р> сериализации / десериализации

    $ new_object = unserialize (serialize ($ your_object))

    Это позволяет получить глубокое копирование с большими затратами в зависимости от сложности объекта.

    Согласно предыдущему комментарию, если у вас есть другой объект в качестве переменной-члена, сделайте следующее:

    class MyClass {
      private $someObject;
    
      public function __construct() {
        $this->someObject = new SomeClass();
      }
    
      public function __clone() {
        $this->someObject = clone $this->someObject;
      }
    
    }
    

    Теперь вы можете заняться клонированием.

    $bar = new MyClass();
    $foo = clone $bar;
    

    Согласно документам ( http://ca3.php.net/language.oop5. клонирование ):

    $a = clone $b;
    

    Просто для пояснения, PHP использует copy при записи, поэтому в основном все является справочной, пока вы не измените ее, но для объектов вам нужно использовать clone и магический метод __clone (), как в принятом ответе.

    Этот код помогает клонировать методы

    class Foo{
    
        private $run=10;
        public $foo=array(2,array(2,8));
        public function hoo(){return 5;}
    
    
        public function __clone(){
    
            $this->boo=function(){$this->hoo();};
    
        }
    }
    $obj=new Foo;
    
    $news=  clone $obj;
    var_dump($news->hoo());
    

    Я проводил тестирование и получил это:     

    class A {
      public $property;
    }
    
    function set_property($obj) {
      $obj->property = "after";
      var_dump($obj);
    }
    
    $a = new A();
    $a->property = "before";
    
    // Creates a new Object from $a. Like "new A();"
    $b = new $a;
    // Makes a Copy of var $a, not referenced.
    $c = clone $a;
    
    set_property($a);
    // object(A)#1 (1) { ["property"]=> string(5) "after" }
    
    var_dump($a); // Because function set_property get by reference
    // object(A)#1 (1) { ["property"]=> string(5) "after" }
    var_dump($b);
    // object(A)#2 (1) { ["property"]=> NULL }
    var_dump($c);
    // object(A)#3 (1) { ["property"]=> string(6) "before" }
    
    // Now creates a new obj A and passes to the function by clone (will copied)
    $d = new A();
    $d->property = "before";
    
    set_property(clone $d); // A new variable was created from $d, and not made a reference
    // object(A)#5 (1) { ["property"]=> string(5) "after" }
    
    var_dump($d);
    // object(A)#4 (1) { ["property"]=> string(6) "before" }
    
    ?>
    

    В этом примере мы создадим класс iPhone и сделаем точную копию из него путем клонирования

    class iPhone {
    
    public $name;
    public $email;
    
        public function __construct($n, $e) {
    
           $this->name = $n;
           $this->email = $e;
    
        }
    }
    
    
    $main = new iPhone('Dark', 'm@m.com');
    $copy = clone $main;
    
    
    // if you want to print both objects, just write this    
    
    echo "<pre>"; print_r($main);  echo "</pre>";
    echo "<pre>"; print_r($copy);  echo "</pre>";
    

    Если вы хотите полностью скопировать свойства объекта в другом экземпляре, вы можете использовать эту технику:

    Сериализуйте его в JSON, а затем удалите сериализацию обратно в Object.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top