Existe uma documentação do ciclo de vida do plug-in?

11

Existe alguma documentação em algum lugar que explica qual é o ciclo de vida dos plug-ins?

Estou iniciando um novo plugin com o estilo OOP e acabei de descobrir que minha classe principal está sendo instanciada muito (graças ao Xdebug e Netbeans).
Eu me pergunto o porquê, e isso me irrita porque estou instanciando um objeto API do Dropbox, e eu realmente não acho que o WordPress instanciaria tanto minha classe principal.

Não encontrei nada relacionado ao ciclo de vida dos plug-ins no Codex nem no Google.

RitonLaJoie
fonte
E aqui, você pesquisou aqui ? :)
brasofilo
20
O YouPorn sempre pode definir sua classe como um singleton stackoverflow.com/questions/203336/…
Bainternet
1
obrigado. Não pensei em 'melhores práticas'. Eu li muitas coisas sobre o Codex, incluindo as Diretrizes de codificação, mas não está aqui. Tentarei o singleton, mas ainda assim, acho estranho que o php do plugin seja chamado várias vezes. Não? Bainternet ter cuidado com o seu autocomplete :)
RitonLaJoie
brasofilo, fazer um singleton ajudaria, mas não responde à pergunta que é: por que o código foi executado várias vezes dentro do meu plugin? A classe OO na URL é ligada está fazendo exatamente o que eu faço
RitonLaJoie
2
Só tive que marcar a pergunta com +1. Apenas para o comentário e voto positivo: D
kaiser

Respostas:

3

Estou iniciando um novo plugin com o estilo OOP

O que significa 'estilo OOP' significa para você? Envolvendo todas as suas funções com uma declaração de classe? Então você está fazendo errado. Você usa a classe como espaço para nome.

e acabei de descobrir que minha classe principal está sendo instanciada bastante

Hã?

class Foo
{
  public function __construct() {
    // assuming your wp-content dir is writeable
    $filename = sprintf( WP_CONTENT_DIR . '/dummyfile-%d.txt', time() );
    $handle = fopen( $filename, 'w' );
    if ( $handle ) {
      fputs( $handle, '-' );
      fclose( $handle );
    }
  }
}

add_action( 'plugins_loaded', function() { new Foo(); } );

Experimente e conte o número de arquivos criados. Se eu experimentar, há um arquivo criado para cada solicitação de página. Isso significa que apenas uma instância da classe Foo para cada solicitação de página.

Vamos tentar uma chamada de ação

class Foo
{
    public function __construct() {

        $this->write_file( 'in_constructor' );
        add_action( 'init', array( $this, 'action_test' ), 10, 0 );

    }

    public function action_test() {

        $this->write_file( 'in_method_with_action_call' );

    }

    public function write_file( $filename ) {

      // assuming your wp-content dir is writeable
      $counter = 1;
      $fname = sprintf( WP_CONTENT_DIR . '/%s-%d.txt', $filename, $counter );

      if ( file_exists( $fname ) ) {
        preg_match( '/(\d)\.txt/is', $fname, $match );
          if ( isset( $match[1] ) ) {
              $counter = (int) $match[1] + 1;
              $fname = sprintf( WP_CONTENT_DIR . '/%s-%d.txt', $filename, $counter );
          }
      }

      $handle = fopen( $fname, 'a+' );
      if ( $handle ) {
          fputs( $handle, '-' );
          fclose( $handle );
      } else {
          throw new Exception( "Cannot open file {$fname} for writing" );
      }

    }
}

add_action( 'plugins_loaded', function() { new Foo(); } );

Se eu procurar no meu diretório wp-content, encontrei dois arquivos. Não mais. Um arquivo é criado quando a instância da classe é criada. E um é criado quando a chamada de ação é concluída.

OK, vamos fazer algumas coisas estúpidas com a nossa instância. Remova o add_action( 'plugins_loaded', .. )e adicione este código:

function bar( $foo ) {

    $baz = $foo;
    return $baz;
}

$f = new Foo();
$GLOBALS['foo'] = $f;

$f2 = $f;
$f3 = &$f;

$f4 = bar( $f2 );
$f5 = bar( $f3 );

Quantos arquivos você espera? Eu espero duas. Um do construtor, outro do método.

Uma nova instância é criada apenas quando o newoperador é usado.

add_action( 'plugins_loaded', 'new_foo', 10, 0 );

function new_foo() {
    // first instance
    new Foo();
}

function bar( $foo ) {
    $baz = $foo;
    return $baz;
}

// second instance here!!
$f = new Foo();
$GLOBALS['foo'] = $f;

$f2 = $f;
$f3 = &$f;

$f4 = bar( $f2 );
$f5 = bar( $f3 );

Agora conto quatro arquivos. Dois do construtor e dois do método Isso ocorre porque o WordPress primeiro inclui o plug-in e depois executa o gancho de ação plugins_loaded.

A melhor prática é usar o gancho de ação em plugins_loadedvez de criar uma instância de uma função porque, se o arquivo do plug-in estiver incluído em qualquer lugar (por exemplo, em outro arquivo do seu plug-in), uma nova instância da classe será criada toda vez que o arquivo for incluído. O gancho de ação plugins_loadedé feito apenas uma vez para cada solicitação de página.

Ralf912
fonte
0

O que pode acontecer é que você passe uma cópia da sua classe para um filtro ou ação. Por exemplo, se você deseja modificar diretamente variáveis ​​de classe dentro de um gancho ou filtro, também deve passar o gancho por referência

add_action("some_action",array(&$this,"somefunction"))

ao invés de

add_action("some_action",array($this,"somefunction"))

Conforme mencionado pela bainternet, você também pode usar um padrão singleton para garantir que um objeto específico seja instanciado apenas uma vez (chamadas adicionais retornam a referência a esse objeto).

Você também pode considerar tornar estáticas algumas funções (fornecendo a elas a palavra-chave estática. Isso geralmente é feito para funções do tipo 'auxiliar' que não interagem com o restante da classe. Métodos estáticos podem ser chamados sem instanciar uma classe.

Você também pode passar funções estáticas para uma ação / filtro:

add_action("some_action",array("ClassName","Method"))

Eu também verifiquei http://codex.wordpress.org/Plugin_API/Action_Reference e descobri que os plugins só podem ser carregados em dois estágios da solicitação (muplugins_loaded e plugins_loaded).

Arevico
fonte
3
Quando um objeto é enviado por argumento, retornado ou atribuído a outra variável, as diferentes variáveis ​​não são alias: elas mantêm uma cópia do identificador, que aponta para o mesmo objeto. do manual do PHP . Em uma chamada ou filtro de ação, a classe é enviada como argumento. Desde o PHP5, não há necessidade de passá-lo como referência.
precisa saber é o seguinte
Eu estou corrigido
Arevico