Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Ola Pessoal
Tenho as seguintes dúvidas sobre referência em php:
1) Sei como funciona a passagem de referência, mais qual a vantagem de fazer isso ? alguém poderia passar um exemplo, explicando a vantagem disso na pratica ?
2) Qual a diferença no exemplo abaixo:
class Test {
public $var;
public function aumentarValor() {
++$this->var;
}
}
$instancia = new Test;
$instanciaCopiada = $instancia; // qual a diferença disso
$instanciaCopiada2 =& $instancia; // para isso
$instancia->aumentarValor();
$instanciaCopiada->aumentarValor();
$instanciaCopiada2->aumentarValor();
var_dump($instancia, $instanciaCopiada, $instanciaCopiada2);
/*
vai imprimir:
object(Test)[1]
public 'var' => int 3
object(Test)[1]
public 'var' => int 3
object(Test)[1]
public 'var' => int 3
*/
Obrigado pelas informações Gabriel. Então podemo dizer que referência é quando dois ou mais objetos precisão ter sincronia de dados para resolver tal problema proposto, ou como vc mesmo falou para, basicamente quando um método necessitava interagir com um objeto, e esse objeto seria alterado sem "aviso prévio" para o script que o solicitou. Correto ?
Acho que a sua exemplificação é mais coerente com o que a referência causa (ou efeito colateral da referência) e não com o que ela é.
No link abaixo há uma explicação (bem simplista) sobre a diferença entre atribuição/cópia e referência.
http://forum.imasters.com.br/topic/516293-recursion-e-loop/?p=2050621
Os objetos, por padrão (na maioria das linguagens de programação), são passados estritamente por referência. Existem algumas situações, mas a primeira com certeza não é por "comportamento padrão". Primeiro existe um problema, depois surge o padrão.
Basicamente:
- Referências são ponteiros (na memória);
- Algumas estruturas de dados usam ponteiros;
- Menor consumo de CPU ao copiar apenas a referência ao invés de toda uma estrutura;
- Menor consumo de memória (vide consumo de CPU).
A cópia de um valor possui, basicamente, o mesmo custo que a cópia de um ponteiro.
1) Partirei do pressuposto que sabes que a referência não é duas variáveis serem iguais ou possuírem os valores compartilhados e sim permitir que duas, ou mais, variáveis apontem para o mesmo local na memória.
Do ponto de vista da orientação a objetos, são, em sua maioria, apenas desvantagens.
Não quero dizer que passar um objeto por referência é ruim. Não é, é o comportamento padrão.
Entretanto, um tipo scalar (int, string, boolean) causa, em muitos pontos, obscuridades, uma vez que um valor alterado indevidamente, e sem a informação de que é por referência, pode "cascatear" inúmeras alterações inesperadas. Esse era um dos problemas do PHP 4, pois ele não tinha um comportamento padrão.
Mas, sempre há sua utilidade. Como por exemplo o MySQLi::bind_result aonde você separa variáveis para cada coluna de um select.
O método PDOStatement::bindParam() tem um comportamento similar. Mas ao invés de ser saída de dados, é a entrada. Todas as variáveis que forem alteradas entre o uso de PDOStatement::bindParam() e PDOStatement::execute() será perpetuado para a execução do statement.
Esses são casos de uso "adequados", pois são situações "controláveis", dentro de um escopo definido, aonde o método não trará alterações inesperadas.
Por outro lado, existem os casos para "burlar o sistema" ou dar um novo comportamento para uma função/método. Veja o caso de preg_match. A função preg_match deve validar uma expressão regular. Ela irá retornar três valores (o que já não é recomendável):
Também, há a possibilidade de ser adicionada algumas opções (flags, offset). Mas, como pode ser visto na assinatura abaixo, o terceiro parâmetro ($matches), provê uma nova funcionalidade ao método.
>
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
O parâmetro $matches é basicamente um retorno "transviado" de parâmetro por referência. O método preg_match segue a linha de assinatura para ser utilizado diretamente dentro de uma estrutura de controle (if, while, for, etc) tal qual outros métodos de validação/filtro (empty, is_array, is_numeric, in_array).
Por último, mas não menos importantes, existem as situações que não são controláveis. Nesse caso, o melhor exemplo é sobre a implementação Immutable da biblioteca DateTime.
Basicamente, quando um método necessitava interagir com um objeto, esse objeto seria alterado sem "aviso prévio" para o script que o solicitou. A explicação você pode ver no link abaixo em conjunto sobre o que é um ValueObject:
http://forum.imasters.com.br/topic/541651-entidade-x-value-object/?p=2163775
2) Diferença alguma. Objetos sempre são passados como referência. Se não me engano, até deveria emitir um erro de strict standars.