web-dev-qa-db-de.com

Gibt es eine Plugin-Lebenszyklusdokumentation?

Gibt es irgendwo eine Dokumentation, die den Lebenszyklus der Plugins erklärt?

Ich starte ein neues Plugin mit OOP -Stil und habe gerade herausgefunden, dass meine Hauptklasse instanziiert wird viel (dank Xdebug und Netbeans).
Ich frage mich warum, und es ärgert mich, weil ich ein Dropbox-API-Objekt instanziiere und ich wirklich nicht dachte, dass WordPress nur meine Hauptklasse so instanziieren würde.

Ich habe weder im Codex noch bei Google etwas im Zusammenhang mit dem Lebenszyklus der Plugins gefunden.

12
RitonLaJoie

Ich starte ein neues Plugin mit dem OOP -Stil

Was bedeutet "OOP-Stil" für Sie? Alle Ihre Funktionen mit einer Klassenanweisung abschließen? Dann machst du es falsch. Sie missbrauchen die Klasse als Namespace.

und ich habe gerade herausgefunden, dass meine Hauptklasse viel instanziiert wird

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

Probieren Sie es aus und zählen Sie die Anzahl der erstellten Dateien. Wenn ich es ausprobiere, wird für jede Seitenanforderung eine one - Datei erstellt. Dies bedeutet, dass für jede Seitenanforderung nur eine Instanz der Foo-Klasse vorhanden ist.

Versuchen wir es mit einem Aktionsaufruf

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

Wenn ich in mein wp-Inhaltsverzeichnis schaue, habe ich zwei Dateien gefunden. Nicht mehr. Eine Datei wird erstellt, wenn die Klasseninstanz erstellt wird. Und eine wird erstellt, wenn der Aktionsaufruf abgeschlossen ist.

OK, lass uns ein paar dumme Sachen mit unserer Instanz machen. Entfernen Sie die add_action( 'plugins_loaded', .. ) und fügen Sie stattdessen diesen Code hinzu:

function bar( $foo ) {

    $baz = $foo;
    return $baz;
}

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

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

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

Wie viele Dateien erwarten Sie? Ich erwarte zwei. Eine vom Konstruktor, eine von der Methode.

Eine neue Instanz wird nur erstellt, wenn der Operator new verwendet wird.

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

Jetzt zähle ich vier Dateien. Zwei vom Konstruktor und zwei von der Methode. Dies liegt daran, dass WordPress zuerst das Plugin einbindet und dann den Aktions-Hook plugins_loaded ausführt.

Es wird empfohlen, den Aktions-Hook plugins_loaded zu verwenden, anstatt eine Instanz aus einer Funktion zu erstellen. Wenn die Plug-in-Datei an einer beliebigen Stelle enthalten ist (z. B. in einer anderen Datei Ihres Plug-ins), wird jedes Mal eine neue Instanz der Klasse erstellt, wenn die Datei enthalten ist . Der Aktions-Hook plugins_loaded wird nur einmal für jede Seitenanforderung ausgeführt.

4
Ralf912

Möglicherweise übergeben Sie eine Kopie Ihrer Klasse an einen Filter oder eine Aktion. Wenn Sie beispielsweise Klassenvariablen in einem Hook oder Filter direkt ändern möchten, sollten Sie den Hook auch als Referenz übergeben

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

anstatt

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

Wie von bainternet erwähnt, können Sie auch ein Singleton-Muster verwenden, um sicherzustellen, dass ein bestimmtes Objekt nur einmal instanziiert wird (weitere Aufrufe geben den Verweis auf dieses Objekt zurück).

Sie können auch erwägen, einige Funktionen statisch zu machen (indem Sie ihnen das Schlüsselwort static geben. Dies wird normalerweise für helferähnliche Funktionen durchgeführt, die nicht mit dem Rest der Klasse interagieren. Statische Methoden können aufgerufen werden, ohne eine Klasse zu instanziieren.

Sie können auch statische Funktionen an eine Aktion/einen Filter übergeben:

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

Ich habe auch http://codex.wordpress.org/Plugin_API/Action_Reference überprüft und festgestellt, dass Plugins nur in zwei Phasen der Anforderung geladen werden können (muplugins_loaded und plugins_loaded).

0
Arevico