Gibt es eine Plugin-Lebenszyklusdokumentation?

11

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 viel instanziiert wird (dank Xdebug und Netbeans).
Ich frage mich, warum, und es ärgert mich, weil ich ein Dropbox-API-Objekt instanziiere, und ich hätte wirklich nicht gedacht, 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.

RitonLaJoie
quelle
Und hier, hast du hier gesucht ? :)
Brasofilo
20
YouPorn kann Ihre Klasse immer als Singleton-Klasse definieren. Stackoverflow.com/questions/203336/…
Bainternet
1
Vielen Dank. Ich habe nicht über "Best Practices" nachgedacht. Ich habe eine Menge Dinge im Codex gelesen, einschließlich der Coding Guidelines, aber sie sind nicht hier. Ich werde dann den Singleton ausprobieren, aber trotzdem finde ich es seltsam, dass das Plugin PHP mehrmals aufgerufen wird. Nein? Bainternet Vorsicht mit Ihrem Autocomplete :)
RitonLaJoie
brasofilo, ein Singleton würde helfen, beantwortet aber nicht die Frage, warum der Code in meinem Plugin mehrmals ausgeführt wird. Die OO-Klasse in der URL, die Sie verlinkt haben, macht genau das, was ich mache
RitonLaJoie
2
Musste nur die Frage +1. Nur für den Kommentar und die Upvotes: D
Kaiser

Antworten:

3

Ich starte ein neues Plugin mit 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 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 das 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 newOperator 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 ausführt plugins_loaded.

Es wird empfohlen, den Aktions-Hook zu verwenden, plugins_loadedanstatt 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, wenn die Datei enthalten ist, eine neue Instanz der Klasse erstellt. Der Aktions-Hook plugins_loadedwird für jede Seitenanforderung nur einmal ausgeführt.

Ralf912
quelle
0

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 von

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 in Betracht ziehen, 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).

Arevico
quelle
3
Wenn ein Objekt als Argument gesendet, zurückgegeben oder einer anderen Variablen zugewiesen wird, sind die verschiedenen Variablen keine Aliase: Sie enthalten eine Kopie des Bezeichners, der auf dasselbe Objekt verweist. aus dem PHP-Handbuch . In einem Aktionsaufruf oder Filter wird die Klasse als Argument gesendet. Seit PHP5 muss es nicht mehr als Referenz übergeben werden.
Ralf912
Ich stehe korrigiert
Arevico