Existe documentação de ciclo de vida de plugins?

12

Existe alguma documentação em algum lugar que explique qual é o ciclo de vida dos plugins?

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

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

    
por RitonLaJoie 24.07.2012 / 16:30

2 respostas

4
  

Estou começando um novo plug-in com estilo OOP

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

  

e eu acabei de descobrir que minha aula principal está sendo muito instanciada

Huh?

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 olhar 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 é feita.

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 dois. Um do construtor, um do método.

Uma nova instância é criada somente quando o operador new é 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 eu conto quatro arquivos. Dois do construtor e dois do método. Isso ocorre porque o WordPress primeiro inclui o plug-in e, em seguida, faz o gancho de ação plugins_loaded .

A melhor prática é usar o gancho de ação plugins_loaded em vez de criar uma instância fora de uma função porque, se o arquivo de 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 é incluído. O gancho de ação plugins_loaded é feito apenas uma vez para cada solicitação de página.

    
por Ralf912 25.04.2013 / 21:46
0

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

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

em vez de

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

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

Você também pode considerar tornar algumas funções estáticas (dando-lhes a palavra-chave static. Isso geralmente é feito para funções do tipo 'auxiliar' que não interagem com o resto da classe. Métodos estáticos podem ser chamados sem instanciar 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 enlace e descobri que os plug-ins só podem ser carregados em dois estágios na solicitação (muplugins_loaded e plugins_loaded) .

    
por Arevico 24.03.2013 / 14:15