¿Existe una documentación del ciclo de vida del complemento?

12

¿Hay alguna documentación en algún lugar que explique cuál es el ciclo de vida de los complementos?

Estoy iniciando un nuevo complemento con estilo OOP, y acabo de descubrir que mi clase principal está siendo instanciada mucho (gracias a Xdebug y Netbeans).
Me pregunto por qué, y me molesta porque estoy instanciando un objeto de API de Dropbox, y realmente no pensé que WordPress simplemente instanciaría mi clase principal tanto.

No he encontrado nada relacionado con el ciclo de vida de los complementos en el Codex ni en Google.

    
pregunta RitonLaJoie 24.07.2012 - 16:30

2 respuestas

4
  

Estoy comenzando un nuevo complemento con estilo OOP

¿Qué significa 'estilo OOP' para ti? ¿Envolviendo todas tus funciones con una declaración de clase? Entonces lo haces mal. Mal uso de la clase como espacio de nombres.

  

y acabo de descubrir que mi clase principal está siendo instanciada mucho

¿Eh?

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(); } );

Pruébelo y cuente la cantidad de archivos creados. Si lo pruebo, hay un archivo creado para cada solicitud de página. Esto significa que solo una instancia de la clase Foo para cada solicitud de página.

Probemos una llamada de acción

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(); } );

Si miro en mi directorio wp-content, encontré dos archivos. No más. Se crea un archivo cuando se crea la instancia de clase. Y uno se crea cuando se realiza la llamada de acción.

Bien, hagamos algunas estupideces con nuestra instancia. Elimine add_action( 'plugins_loaded', .. ) y agregue este código en su lugar:

function bar( $foo ) {

    $baz = $foo;
    return $baz;
}

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

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

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

¿Cuántos archivos esperas? Espero dos. Uno del constructor, uno del método.

Se crea una nueva instancia solo cuando se usa el operador new .

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 );

Ahora cuento cuatro archivos. Dos del constructor y dos del método. Esto se debe a que WordPress primero incluye el complemento y luego realiza el gancho de acción plugins_loaded .

La mejor práctica es usar el gancho de acción plugins_loaded en lugar de crear una instancia a partir de una función porque, si el archivo de complemento se incluye en cualquier lugar (por ejemplo, en otro archivo de su complemento), se crea una nueva instancia de la clase Cada vez que el archivo está incluido. El gancho de acción plugins_loaded se realiza solo una vez por cada solicitud de página.

    
respondido por el Ralf912 25.04.2013 - 21:46
0

Lo que podría suceder es que pase una copia de su clase a un filtro o acción. Por ejemplo, si desea modificar directamente las variables de clase dentro de un enlace o filtro, también debería pasar el enlace por referencia

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

en lugar de

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

Como lo menciona bainternet, también puede usar un patrón de singleton para asegurarse de que un objeto específico se instancia solo una vez (las llamadas posteriores devuelven la referencia a ese objeto).

También podría considerar hacer algunas funciones estáticas (dándoles la palabra clave estática. Esto generalmente se hace para funciones similares a "ayudantes" que no interactúan con el resto de la clase. Se pueden llamar métodos estáticos sin instanciar clase.

También puede pasar funciones estáticas a una acción / filtro:

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

También verifiqué enlace y encontré que los complementos solo se pueden cargar en dos etapas en la solicitud (muplugins_loaded y plugins_loaded) .

    
respondido por el Arevico 24.03.2013 - 14:15

Lea otras preguntas en las etiquetas