Existe-t-il une documentation sur le cycle de vie des plugins?

12

Existe-t-il quelque part une documentation qui explique quel est le cycle de vie des plugins?

Je commence un nouveau plugin avec le style OOP et je viens de découvrir que ma classe principale est instanciée beaucoup (grâce à Xdebug et Netbeans).
Je me demande pourquoi, et cela me gêne parce que j'instancie un objet Dropbox-API, et je ne pensais vraiment pas que WordPress instancierait autant mon cours principal.

Je n'ai rien trouvé concernant le cycle de vie des plugins dans le Codex ni sur Google.

    
posée RitonLaJoie 24.07.2012 - 16:30

2 réponses

4
  

Je commence un nouveau plugin avec le style POO

Que signifie "style POO" pour vous? Enveloppant toutes vos fonctions avec une déclaration de classe? Alors tu le fais mal. Vous avez mal utilisé la classe comme espace de noms.

  

et je viens de découvrir que ma classe principale est beaucoup instanciée

Hein?

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

Essayez-le et comptez le nombre de fichiers créés. Si je l’essaye, un un fichier est créé pour chaque demande de page. Cela signifie qu'une seule instance de la classe Foo pour chaque demande de page.

Essayons un appel d'action

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 je regarde dans mon répertoire wp-content, j'ai trouvé deux fichiers. Pas plus. Un fichier est créé lors de la création de l'instance de classe. Et l'un est créé lorsque l'appel à l'action est terminé.

OK, faisons des choses stupides avec notre instance. Supprimez le add_action( 'plugins_loaded', .. ) et ajoutez ce code à la place:

function bar( $foo ) {

    $baz = $foo;
    return $baz;
}

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

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

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

Combien de fichiers attendez-vous? J'attends deux. Un du constructeur, un de la méthode.

Une nouvelle instance est créée uniquement lorsque l'opérateur new est utilisé.

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

Maintenant, je compte quatre fichiers. Deux du constructeur et deux de la méthode. En effet, WordPress inclut d’abord le plugin, puis le crochet d’action plugins_loaded .

La meilleure pratique consiste à utiliser le crochet d'action plugins_loaded au lieu de créer une instance hors d'une fonction car, si le fichier de plug-in est inclus n'importe où (par exemple dans un autre fichier de votre plug-in), une nouvelle instance de la classe est créée. chaque fois que le fichier est inclus. Le crochet d’action plugins_loaded n’est exécuté qu’une fois pour chaque demande de page.

    
réponse donnée Ralf912 25.04.2013 - 21:46
0

Ce qui pourrait arriver, c’est que vous transmettiez une copie de votre classe à un filtre ou à une action. Par exemple, si vous souhaitez modifier directement les variables de classe dans un hook ou un filtre, vous devez également passer le hook par référence

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

au lieu de

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

Comme mentionné par bainternet, vous pouvez également utiliser un modèle singleton pour vous assurer qu'un objet spécifique n'est instancié qu'une seule fois (les appels suivants renvoient la référence à cet objet).

Vous pouvez également rendre certaines fonctions statiques (en leur donnant le mot-clé static. Cela est généralement utilisé pour les fonctions de type "helper" qui n'interagissent pas avec le reste de la classe. Les méthodes statiques peuvent être appelées sans instanciation de classe.

Vous pouvez également transmettre des fonctions statiques à une action / un filtre:

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

J'ai également vérifié enlace et constaté que les plug-ins ne peuvent être chargés qu'à deux étapes de la requête (muplugins_loaded et plugins_loaded) .

    
réponse donnée Arevico 24.03.2013 - 14:15

Lire d'autres questions sur les étiquettes