Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Andre Luizao

Duvida no operador de referência em PHP

Recommended Posts

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
*/

Compartilhar este post


Link para o post
Compartilhar em outros sites

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):

  • 1 caso a ER casar;
  • 0 caso a ER não casar;
  • False caso houver um erro.

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.

Compartilhar este post


Link para o post
Compartilhar em outros sites

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 ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

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.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.