Ir para conteúdo

POWERED BY:

Arquivado

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

criatividade zero

[Resolvido] __construct e __destruct

Recommended Posts

ja li no manual do php sobre __construct e __destruct e botei pra rodar todos exemplos disponiveis

uma consulta mysql pode ser open no construct e close no destruct, ate ai tudo bem, esta entendido

o problema é que muitos exemplos vejo tratarem o destruct como desnecessario, outros vejo um __destruct vazio

 

queria saber se posso usar o destruct para qualquer ação final, como gravar um log ou o destruct deve ser 'reservado' ao metodo inicial, tipo fechar a conexão

 

 

class A {
	function __construct() {
		...
	}

	function __destruct() {
		...
	}
}

class B extends A {
	function __construct() {
		...
	}

	function __destruct() {
		...
	}
}

nesse exemplo acima eu teria a classe A com o destruct gerando log e a classe B poderia ser uma conexão com destruct fechando

 

o resultado seria

__construct A

__construct B

__destruct B

__destruct A

 

isso estaria correto?

Compartilhar este post


Link para o post
Compartilhar em outros sites

alguem sabe qual a ordem de execução desses metodos???

 

 

$db = new db();
echo '<p>texto</p>';

saida:

__construct db

texto

__destruct db

 

 

nao deveria ser assim??

__construct db

__destruct db

texto

 

 

um sobrepoe o outro

qual a prioridade de execução afinal?

Compartilhar este post


Link para o post
Compartilhar em outros sites

alguem sabe qual a ordem de execução desses metodos???

qual a prioridade de execução afinal?

 

O __construct é acionado no instante que se cria uma instância do objeto.

O __destruct é acionado no instante que o objeto é destruído.

 

Se você não destruir o objeto antes do fim da execução da aplicação, ele só sera destruído quando todo o código terminar de executar.

 

<?php
class Example {
public function __construct(){
	printf( "Construindo uma instância de %s\n" , __CLASS__ );
}

public function __destruct(){
	printf( "Destruindo %s\n" , __CLASS__ );
}

public function test(){
	printf( "Testando\n" );
}
}

$example = new Example();

$example->test();

printf( "Instância de: %s\n" , get_class( $example ) );

 

Nesse caso, a saída será:

 

Construindo uma instância de Example

Testando

Instância de: Example

Destruindo Example

 

Perceba que o "Destruindo Example" só aparece no final, logo no término da execução do código.

 

Agora, se você destruir o objeto antes do fim da execução do código:

 

<?php
class Example {
public function __construct(){
	printf( "Construindo uma instância de %s\n" , __CLASS__ );
}

public function __destruct(){
	printf( "Destruindo %s\n" , __CLASS__ );
}

public function test(){
	printf( "Testando\n" );
}
}

$example = new Example();

$example->test();

printf( "Instância de: %s\n" , get_class( $example ) );

$example = null;

printf( "Agora o objeto foi destruído antes do fim da execução do código...\n" );

 

A saída será:

Construindo uma instância de Example

Testando

Instância de: Example

Destruindo Example

Agora o objeto foi destruído antes do fim da execução do código...

 

Ou seja, o __destruct será acionado quando o objeto for destruído, se você não destruir no meio da execução, o PHP se encarregará de destruir todos seus objetos logo que terminar a execução do código.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

porr@ esses metodos são magicos mesmo

uma parada que aparecia fora de ordem... sumiu

 

quando estendia a classe e omitia o destruidor, ele 'dobrava' repetindo o destruct da classe principal

__construct .principal

__construct .secundario

texto na classe secundaria

__destruct .principal

__destruct .principal

 

 

agora esta assim

__construct .principal

__construct .secundario

texto na classe secundaria

__destruct .principal

 

 

imagino que o correto seria o 2º caso

tendo uma classe principal com const. e dest. e uma estendida apenas com const. o destruidor será acionado apenas 1 vez, correto?!

 

Mr M, revele este segredo magico

hehhehehehhe

Compartilhar este post


Link para o post
Compartilhar em outros sites

tendo uma classe principal com const. e dest. e uma estendida apenas com const. o destruidor será acionado apenas 1 vez, correto?!

 

hummmm....

 

Você não testou ai ????

 

<?php
class Example {
public function __construct(){
	printf( "Construindo %s\n" , get_class( $this ) );
}

public function __destruct(){
	printf( "Destruindo %s\n" , get_class( $this ) );
}
}

class Test extends Example {
public function __construct(){
	parent::__construct();

	printf( "Dentro de %s\n" , __CLASS__ );
}
}

$test = new Test();

 

Saída:

Construindo Test

Dentro de Test

Destruindo Test

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você não testou ai ????

 

ja perdi a conta de qts arquivos criei so pra testar esses metodos

e ja testei esses que você postou tb

 

 

so quero ter certeza de estar montando corretamente

essa seria a ordem para controi/destroi em classes seguidas sem 'extends'?

$classeA = new classeA();

$classeB = new classeB();

$classeC = new classeC();

 

__construct .A

__construct .B

__construct .C

__destruct .C

__destruct .B

__destruct .A

Compartilhar este post


Link para o post
Compartilhar em outros sites

essa seria a ordem para controi/destroi em classes seguidas sem 'extends'?

 

Depende, veja só:

 

<?php
class A {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
}
}

class B extends A {
public function __construct(){
	parent::__construct();
	printf( "Construindo %s\n" , __CLASS__ );
}
}

class C extends B {
public function __construct(){
	parent::__construct();
	printf( "Construindo %s\n" , __CLASS__ );
}
}

$c = new C();

 

Saída:

Construindo A

Construindo B

Construindo C

 

Que é diferente de:

 

<?php
class A {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
}
}

class B extends A {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
	parent::__construct();
}
}

class C extends B {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
	parent::__construct();
}
}

$c = new C();

 

Saída:

Construindo C

Construindo B

Construindo A

 

EDIT:

 

Não percebi o 'sem extends', veja só:

<?php
class A {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
}

public function __destruct(){
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

class B {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
}

public function __destruct(){
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

class C {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
}

public function __destruct(){
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

$a = new A();
$b = new B();
$c = new C();

 

Saída:

Construindo A

Construindo B

Construindo C

Destruindo C

Destruindo B

Destruindo A

 

EDIT 2:

 

Outro exemplo interessante:

 

<?php
class A {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
}

public function __destruct(){
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

class B extends A {
public function __construct(){
	parent::__construct();
	printf( "Construindo %s\n" , __CLASS__ );
}

public function __destruct(){
	parent::__destruct();
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

class C extends B {
public function __construct(){
	parent::__construct();
	printf( "Construindo %s\n" , __CLASS__ );
}

public function __destruct(){
	parent::__destruct();
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

$c = new C();

 

Saída:

Construindo A

Construindo B

Construindo C

Destruindo A

Destruindo B

Destruindo C

 

Que é diferente de:

<?php
class A {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
}

public function __destruct(){
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

class B extends A {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
	parent::__construct();
}

public function __destruct(){
	parent::__destruct();
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

class C extends B {
public function __construct(){
	printf( "Construindo %s\n" , __CLASS__ );
	parent::__construct();
}

public function __destruct(){
	parent::__destruct();
	printf( "Destruindo %s\n" , __CLASS__ );
}
}

$c = new C();

 

Saída:

Construindo C

Construindo B

Construindo A

Destruindo A

Destruindo B

Destruindo C

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

mas a duvida paira no __destruct

coloquei um __destruct em cada classe e retornou

 

Construindo A

Construindo B

Construindo C

Destruindo A

Destruindo B

Destruindo C

 

usei no B e C

public function __destruct(){
                parent::__destruct();
                printf( "<br />Destruindo %s\n" , __CLASS__ );
        }

 

 

o ponto que me causa enorme duvida, é em relação com a ordem de execução

se eu tiver

 

$classeA = new classeA();

e na classe A eu chamo $classeB = new classeB();

 

o construct e o destruct de classeB devem ser entre construct e o destruct da classeA

isso é o metodo correto da ordem?

Construindo A

Construindo B

Destruindo B

Destruindo A

Compartilhar este post


Link para o post
Compartilhar em outros sites

então...seguindo os seus exemplos

 

1º caso

Construindo A+B+C

Destruindo C+B+A

 

2º caso

Construindo A+B+C

Destruindo A+B+C

 

 

o 2º caso não seria 'incorreto'?

digo porque a logica do 1º me parece mais coerente em termos de fluxo

seria o mesmo que:

 

abre a porta do predio (A)
   abre o elevador (B)
      abre a porta de casa (C)
      fecha a porta de casa (C)
   fecha o elevador (B)
fecha a porta do predio (A)

Compartilhar este post


Link para o post
Compartilhar em outros sites

abre a porta do predio (A)
 abre o elevador (B)
 abre a porta de casa (C)
 fecha a porta de casa (C)
 fecha o elevador (B)
fecha a porta do predio (A)

Tente pensar assim:

 

Você tem 3 caixas desmontadas, a primeira de 50 centímetros cúbicos, a segunda de 25 centímetros cúbicos e a terceira de 12.5 centímetros cúbicos.

 

Você constrói a primeira caixa.

Você constrói a segunda caixa dentro da primeira.

Você constrói a terceira caixa dentro da segunda.

 

Feito isso, você pisa na primeira.

 

O ato de pisar na primeira fará com que a segunda seja destruída e, por fim a terceira, por consequência, também será destruída.

 

<?php
class Caixa {
private $h;
private $w;
private $d;
private $c;

public function __construct( $h , $w , $d , $l = 1 ){
	$this->h = $h;
	$this->w = $w;
	$this->d = $d;

	printf( "Construindo caixa %dx%dx%d\n" , $h , $w , $d );

	if ( $l < 3 ){
		$this->c = new Caixa( $h / 2 , $w / 2 , $d / 2 , ++$l );
	}
}

public function __destruct(){
	printf( "Destruindo caixa %dx%dx%d\n" , $this->h , $this->w , $this->d );
}
}

$caixa_50_50_50 = new Caixa( 50 , 50 , 50 );

 

Saída:

Construindo caixa 50x50x50

Construindo caixa 25x25x25

Construindo caixa 12x12x12

Destruindo caixa 50x50x50

Destruindo caixa 25x25x25

Destruindo caixa 12x12x12

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

então pode-se dizer que ambas as formas estão corretas?!

 

fiz um grafico pra mostrar como isso esta sendo entendito aos meus olhos... acho que fica mais facil de explicar minha duvida...

:)

 

 

Imagem Postada

 

 

no modelo 1 é o exemplo das caixas que você deu

no modelo 2 vejo o seguinte; o processo A executa uma ação e repassa ao B que por sua vez repassa ao C

ao final de cada processo - seria o __destruct - posso fazer uma analise das informações e ter certeza que que nada foi corrompido

 

mas no modelo 1 isso ja não seria possivel pq uma sequencia termina antes da que chamou...

ex; não poderia verificar ao fim do processo A a validade dos dados finais do processo B e C

 

a ordem de inicio e fim depende da aplicação, correto???

Compartilhar este post


Link para o post
Compartilhar em outros sites

então pode-se dizer que ambas as formas estão corretas?!

a ordem de inicio e fim depende da aplicação, correto???

 

Perfeito, tudo depende da modelagem da sua aplicação.

 

fiz um grafico pra mostrar como isso esta sendo entendito aos meus olhos... acho que fica mais facil de explicar minha duvida...

 

Procure estudar UML, vai lhe ajudar muito na hora de modelar uma aplicação.

 

No caso, o diagrama de sequência seria:

 

Imagem Postada

 

Mas nada impede que sua aplicação prefira destruir a caixa3 antes da caixa2 e a caixa2 antes da caixa1.

 

Quando você for modelar sua aplicação, você precisará decidir qual a ordem de destruição dos objetos para que, caso um objeto seja destruído, não interfira na execução de outro objeto.

 

;)

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Perfeito, tudo depende da modelagem da sua aplicação.

 

aleluia, acertei uma :)

hehhehe

 

 

Procure estudar UML, vai lhe ajudar muito na hora de modelar uma aplicação.

 

Mas nada impede que sua aplicação prefira destruir a caixa3 antes da caixa2 e a caixa2 antes da caixa1.

 

Quando você for modelar sua aplicação, você precisará decidir qual a ordem de destruição dos objetos para que, caso um objeto seja destruído, não interfira na execução de outro objeto.

 

vou dar uma estudada em UML - completamente leigo sobre o assunto

a duvida surgiu em torno de 'regra' e 'boa pratica'

não sabia se existia uma regra para seguir à risca sobre a ordem de inicio e fim

como a aplicação esta 'sequencial', vai de um pro outro, ha a necessidade de ordenar o fim da mesma forma que inicia A-B-C ... C-B-A; e não sabia se estava correto

 

valeu pelo grafico :)

 

isso tudo pra um simples esquema MVC, o problema é que são varias sessões que preciso verificar, comparar e repassar e mais alguns modulos - e so quro ter certeza de estar no trilho certo

 

 

essa duvida esta resolvida... por hora

hehehehehe

obrigadão

 

[]s

Compartilhar este post


Link para o post
Compartilhar em outros sites

isso tudo pra um simples esquema MVC, o problema é que são varias sessões que preciso verificar, comparar e repassar e mais alguns modulos - e so quro ter certeza de estar no trilho certo

 

Visite também o fórum de Modelagem de Dados e Arquitetura, pode ser interessante.

 

essa duvida esta resolvida... por hora

obrigadão

;)

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.