Pergunta

No PHP5, é o método () garantido para ser chamado para cada instância do objeto __destruct? exceções no programa pode impedir que isto aconteça?

Foi útil?

Solução

O destrutor será chamado quando as todas as referências são liberados, ou quando o termina script. Presumo Isto significa que quando o script termina corretamente. Eu diria que as exceções críticas não garantiria o destruidor de ser chamado.

O documentação PHP é um pouco fina, mas diz que as exceções no processo de destruição causará questões.

Outras dicas

Também é importante ressaltar que, no caso de uma subclasse que tem a sua própria destruição, o destruidor pai é não chamado automaticamente.

Você tem que chamar explicitamente parent :: __ destruct () a partir da subclasse __ destruct () método se a classe pai faz qualquer limpeza necessária.

Na minha experiência destruidores será sempre chamado no PHP 5.3, mas ser avisado que, se algum pedaço de código chama exit () ou se ocorre um erro fatal, o PHP irá chamar destruidores em "qualquer" ordem (eu acho que a ordem real é a ordem na memória ou a ordem da memória foi reservada para os objetos. na prática, este fim é quase sempre problemático). Isso é conhecido como "sequência de encerramento" na documentação do PHP.

documentação PHP de destruidores diz:

5 PHP apresenta um conceito semelhante para destruidor de outras linguagens orientada por objectos, tais como C ++. O método destrutor será chamado assim que não existem outras referências a um determinado objeto, ou em qualquer ordem durante a sequência de encerramento.

Como resultado, se você tem classe X que contém uma referência para Y, o destruidor de X pode ser chamado após o destruidor de Y já foi chamado. Felizmente, a referência a Y não era tão importante ... Oficialmente este não é um bug porque tem sido documentado.

No entanto, é muito difícil de solucionar esse problema porque oficialmente PHP não fornece nenhuma maneira de saber se destruidor é chamado normalmente (destruidores são chamados na ordem correta) ou destruidores são chamados de "qualquer" ordem de onde você não pode usar dados de objetos referenciados porque aqueles já pode ter sido destruído. Pode-se resolver este falta de detecção utilizando debug_backtrace () e examinando a pilha. Falta de pilha normal, parece implicar "sequência de encerramento" com PHP 5.3, mas isso também é indefinido. Se você tem referências circulares, os destruidores desses objetos não será chamado em tudo com PHP 5.2 ou menor e será chamado de "qualquer" ordem durante "sequência de encerramento" em PHP 5.3 ou superior. Para referências circulares, lá não existe uma ordem lógica "correta" para "qualquer" ordem é bom para aqueles.

Existem algumas exceções (este é PHP depois de tudo):

  • se exit() é chamado em outro destructor, nenhum destruidores restantes não será chamado ( http://php.net/manual/en/language.oop5.decon.php )
  • Se o erro FATAL ocorre em qualquer lugar (muitas causas possíveis, por exemplo, tentando lançar uma exceção a partir de qualquer outro processo de destruição poderia ser uma causa), nenhum destruidores restantes não será chamado.

Claro que, se o motor PHP atinge falha de segmentação ou algum outro erro interno ocorre, então todas as apostas estão fora.

Se você quiser entender o atual implementação de "sequência de encerramento", consulte https://stackoverflow.com/ um / 14101767 . Note-se que essa implementação pode mudar em futuras versões do PHP.

Há um bug atual com referências circulares que pára o método de destruição sendo chamado implicitamente. http://bugs.php.net/bug.php?id=33595 Deve ser fixado em 5,3

Use a função de desligamento se você quer ir com certeza: register_shutdown_function ( )

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top