Parece que no PHP os objetos são passados por referência. Mesmo operadores de atribuição não parecem estar criando uma cópia do objeto.
Aqui está uma prova simples e artificial:
<?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'
?>
Nos dois casos de impressão, estou recebendo 'depois'
Então, como passo $ a para set_b () por valor, não por referência?
php
copy
clone
shallow-copy
Nick Stinemates
fonte
fonte
(object) ((array) $objectA)
pode resultar nos mesmos resultados desejados com melhor desempenho do que emclone $objectA
ounew stdClass
.Respostas:
No PHP 5+, os objetos são passados por referência. No PHP 4, eles são passados por valor (é por isso que o tempo de execução é passado por referência, que ficou obsoleto).
Você pode usar o operador 'clone' no PHP5 para copiar objetos:
Além disso, são apenas objetos que são passados por referência, não tudo como você disse na sua pergunta ...
fonte
$a = new stdClass; $b =& $a; $a = 42; var_export($b);
aqui$b
está uma referência à variável$a
; se você substituir=&
com um normais=
, é não uma referência, e ainda aponta para o objeto original.As respostas são comumente encontradas em livros Java.
clonagem: se você não substituir o método clone, o comportamento padrão será a cópia superficial. Se seus objetos tiverem apenas variáveis de membros primitivas, tudo estará bem. Mas em uma linguagem sem letra com outro objeto como variável membro, é uma dor de cabeça.
serialização / desserialização
$new_object = unserialize(serialize($your_object))
Isso permite uma cópia profunda com um alto custo, dependendo da complexidade do objeto.
fonte
$a = clone $b
sem__clone()
métodos mágicos em jogo) é equivalente a olhar para cada uma das propriedades do objeto$b
no termo e atribuir à mesma propriedade em um novo membro da mesma classe, usando=
. Propriedades que são objetos não terãoclone
d nem objetos dentro de uma matriz; o mesmo vale para variáveis vinculadas por referência; tudo o resto é apenas um valor e é copiado como em qualquer tarefa.Call to method __clone from invalid context
:)$new_date = (clone $date_start)->subDays(1);
Falha com o()
, se eu removê-los, recebo um erro diferente. O problema é que estamos usando exatamente o mesmo php 7.2.3 e o meu funciona bem. Alguma ideia? Procurado em todos os lugares ..De acordo com o comentário anterior, se você tiver outro objeto como variável de membro, faça o seguinte:
Agora você pode fazer a clonagem:
fonte
De acordo com os documentos ( http://ca3.php.net/language.oop5.cloning ):
fonte
Apenas para esclarecer, o PHP usa copy on write, então basicamente tudo é uma referência até você modificá-lo, mas para objetos você precisa usar o clone e o método mágico __clone () como na resposta aceita.
fonte
Esse código ajuda a clonar métodos
fonte
Eu estava fazendo alguns testes e consegui isso:
fonte
Neste exemplo, criaremos a classe iPhone e faremos uma cópia exata dela clonando
fonte
Se você deseja copiar completamente as propriedades de um objeto em uma instância diferente, convém usar esta técnica:
Serialize-o para JSON e des serialize-o novamente para Object.
fonte