Eu pensei que seria mais simples. Eu joguei vários dias até que tudo funciona corretamente.

A idéia é implementar o seguinte diagrama desenhado com ArgoUML :

diagramadeclase11 Patrón singleton con herencia en PHP

Ou seja, uma classe base que herda outra.

O cenário é webservices diferentes que eu tenho que chamar dentro do aplicativo. O que fiz foi mapear cada webservice a uma classe que contém os mesmos métodos do webservice, de modo que o que você tem que fazer contra o webservice é feita contra classes com o mesmo nome e com os mesmos métodos de retornar diretamente a informação de retorno.

Desde o início, foram criados para as classes de webservices variam de uma classe base que tinha a característica comum de todos, isto é, as chamadas para o webservices e controlo dos mesmos erros e evitar a duplicação essa funcionalidade em cada classe.

Então eu decidi que cada classe deve implementar o padrão Singleton para garantir que apenas tinha uma instância da mesma classe em todos os momentos e evitar que o código está viciada por instanciar um novo a cada vez que você precisar.

A solução geral era, portanto, implementar o singleton para a classe pai e tudo o que se estendem desde tuviesen singleton automaticamente e não ter que implementar em cada um deles. O ideal é bom, a prática era muito pior.

O primeiro teste foi declarar a getInstancia método responsável por garantir o singleton como se segue:

  1. $instancia = null ; privado estático $ instance = null;
  2. function getInstancia ( $asurl ) público estático getInstancia função ($ asurl)
  3. (
  4. ; ReturnValue $ = null;
  5. ! isset ( self:: $instancia ) ) { if (! isset (self:: $ exemplo)) (
  6. $ Classe = _CLASS_;
  7. $class ( $asurl ) ; self:: $ exemplo = $ classe nova ($ asurl)
  8. )
  9. ; ReturnValue = self:: $ $ instance;
  10. ; return $ returnValue;
  11. )

Supunha-se que isso seria, na falta de uma nova instância do objeto que foi chamado, no nosso caso, por exemplo, a classe 1. Mas a partir dos testes, percebemos que _CLASS_ não retornar o nome da classe é chamado, mas a classe em que é executado, neste caso base, que não serviu-nos para o nosso propósito.

Next é uma função do PHP que devolve-nos o que precisamos, ou seja, o nome da classe com o nome: get_called_class. Pena que está disponível a partir do PHP 5.3 (em beta). No entanto, encontramos uma aplicação alternativa dessa função válido para versões anteriores do PHP.

  1. ! function_exists ( 'get_called_class' ) ) { if (! function_exists ('get_called_class')) (
  2. get_called_class função () (
  3. ( ) ; Bt = $ debug_backtrace ();
  4. ( $bt [ 1 ] [ 'file' ] ) ; $ Linhas = arquivo ($ bt [1 ['arquivo]']);
  5. '/([a-zA-Z0-9 \_ ]+)::' . $bt [ 1 ] [ 'function' ] . '/' , $lines [ $bt [ 1 ] [ 'line' ] -1 ] , $matches ) ; preg_match '/ ([a-zA-Z0-9 \ _ ]+)::'. $ bt [1] "função" [] (.' / ', $ linhas [$ bt [1 [' linha] '] -1], $ matches);
  6. [ 1 ] ; return $ matches [1];
  7. )
  8. )

Com isso, poderíamos criar a instância da classe que precisávamos do singleton, mas ainda assim uma surpresa nos aguardava. Nós não poderíamos instanciar mais de uma classe (outros) a partir do qual ele herdou de um pai, embora ele assume diferentes objetos para herdar o mesmo tem que usar a mesma instância do singleton e não deixá-lo como exemplo (a variável código anterior) já está gerado e de outra forma.

Aqui está um exemplo para uma melhor visualização. Nós criamos uma instância de Class1, o singleton retornará uma nova instância e não existe. Agora crie outro Class2. O objeto retornado é do tipo Class1. Embora queremos criar objetos diferentes (Class1 e Class2), a instância de banco de dados é compartilhada por ambos. Como eu instanciar Class1, Class1 é exemplo do tipo, que retorna para instanciar o Class2 instância já criada, Class1. Pudemos ver que a instância (variável) é criado e é do mesmo tipo que você deseja criar uma instância nova, mas de criar as Class2 (novo) iria destruir o velho (Classe 1), de modo que perderia o efeito, e não é isso que procurado.

A solução? Pode parecer um pouco complicado, mas é o seguinte:

Base

  1. classe osusnet_com_Base
  2. (
  3. = ; private $ asurl = ";
  4. $instancia = array ( ) ; privado estático $ exemplo = array ();
  5. = null ; private $ iVersion = null;
  6. = ; private $ sAsConsumer = ";
  7. = 0 ; private $ debug = 0;
  8. $asurl ) protegido função __construct ($ asurl)
  9. (
  10. $asurl == "" ) { if ($ asurl == "") (
  11. ; return false;
  12. { Else ()
  13. = $asurl ; Este -> = $ asurl asurl $;
  14. = 1 ; $ This-> iVersion - = 1;
  15. = "kk" ; $ This-> sAsConsumer - = kk "
  16. = 0 ; $ This-> - debug = 0;
  17. )
  18. )
  19. function getInstancia ( $asurl ) público estático getInstancia função ($ asurl)
  20. (
  21. ; ReturnValue $ = null;
  22. ; $ Classe = get_called_class ();
  23. ! isset ( self:: $instancia [ $class ] ) ) { if (! isset (self:: $ exemplo [$ class])) (
  24. $class ] = new $class ( $asurl ) ; :: $ Exemplo self [$ class] = $ classe nova ($ asurl)
  25. [ $class ] ; $ ReturnValue = self:: $ exemplo [$] aula;
  26. )
  27. ; return $ returnValue;
  28. )
  29. )

Class1

  1. osusnet_com_Base osusnet_com_Clase1 classe estende osusnet_com_Base
  2. (
  3. $cookie ) Função Pública GetUserContext ($ cookie)
  4. (
  5. )
  6. CheckStateUser função pública ()
  7. (
  8. )
  9. public function login ()
  10. (
  11. )
  12. )

Ou seja, de instância (variável) torna-se uma matriz onde armazenar um elemento para cada instância de cada uma das classes que herdam dela. Se já criou um tipo de retorno que será exemplo, caso contrário, ele cria e disponibiliza para o prosseguimento. A base é única, mas ele cria um objeto de cada classe disponível.

Como qualquer padrão singleton para usar para fazer:

  1. ( $url ) ; $ Instância osusnet_com_Clase1 =:: getInstancia ($ url);

Lembre-se que o construtor é protegido de modo que qualquer tentativa de querer instanciar a classe destes directamente irá falhar, tente fazer:

  1. osusnet_com_Clase1 ( ) ; $ Instância = new osusnet_com_Clase1 ();

Qual não é o comportamento em outros idiomas, os meus anos de Java já estão um pouco atrás, nem mesmo se a teoria de OOP é o comportamento descrito aqui ou má aplicação de PHP, eu não sou um especialista na teoria do p ROGRAMAÇÃO orientada a objeto. Minha lógica diz-me que, se uma instância de classe de um tipo, você deve instanciar todos, sem partilha de uma classe base, como faz sentido que, se toda a gama de base e onde ele tem a instância singleton e getInstancia estática ou comum a todos. Quanto mais eu penso nisso, mais eu mess.

Pelo menos eu achei uma solução.

Se você tem revelado útil este artigo ... Compartilhe!