Czy istnieje dokumentacja cyklu życia wtyczki?

11

Czy jest gdzieś dokumentacja, która wyjaśnia, jaki jest cykl życia wtyczek?

Zaczynam nową wtyczkę w stylu OOP i właśnie dowiedziałem się, że moja główna klasa jest bardzo aktywna (dzięki Xdebug i Netbeans).
Zastanawiam się, dlaczego i denerwuje mnie to, ponieważ inicjuję obiekt Dropbox-API, i naprawdę nie sądziłem, że WordPress po prostu zainicjuje moją główną klasę.

Nie znalazłem nic związanego z cyklem życia wtyczek w Kodeksie ani w Google.

RitonLaJoie
źródło
A tutaj, szukałeś tutaj ? :)
brasofilo
20
YouPorn zawsze może zdefiniować twoją klasę jako singleton stackoverflow.com/questions/203336/…
Bainternet
1
dzięki. Nie myślałem o „najlepszych praktykach”. Przeczytałem wiele rzeczy na temat Kodeksu, w tym Wytyczne kodowania, ale nie ma ich tutaj. Spróbuję wtedy singletona, ale wciąż dziwne jest, że wtyczka php jest wywoływana wiele razy .. Nie? Bainternet, bądź ostrożny z autouzupełnianiem :)
RitonLaJoie
brasofilo, utworzenie singletonu pomogłoby, ale nie odpowiada na pytanie: dlaczego kod jest uruchamiany wiele razy w mojej wtyczce? Klasa OO w linkowanym adresie URL robi dokładnie to, co robię
RitonLaJoie
2
Musiałem dać +1 pytaniu. Tylko dla komentarza i opinii: D
kaiser

Odpowiedzi:

3

Zaczynam nową wtyczkę w stylu OOP

Co oznacza dla Ciebie „styl OOP”? Zawijasz wszystkie funkcje w instrukcję klasy? Więc robisz to źle. Tęsknisz za klasą jako przestrzenią nazw.

i właśnie dowiedziałem się, że moja główna klasa jest często zaszczepiona

Co?

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

Wypróbuj i policz liczbę utworzonych plików. Jeśli spróbuję, dla każdego żądania strony zostanie utworzony jeden plik. Oznacza to tylko jedno wystąpienie klasy Foo dla każdego żądania strony.

Spróbujmy wezwania do działania

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

Jeśli zajrzę do mojego katalogu treści wp, znalazłem dwa pliki. Już nie. Jeden plik jest tworzony podczas tworzenia instancji klasy. Jeden jest tworzony po zakończeniu akcji.

OK, zróbmy kilka głupich rzeczy z naszą instancją. Usuń add_action( 'plugins_loaded', .. )i dodaj ten kod zamiast:

function bar( $foo ) {

    $baz = $foo;
    return $baz;
}

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

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

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

Ile oczekujesz plików? Oczekuję dwóch. Jeden od konstruktora, drugi od metody.

Nowa instancja jest tworzona tylko wtedy, gdy newużywany jest operator.

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

Teraz liczę cztery pliki. Dwa z konstruktora i dwa z metody. Wynika to z faktu, że WordPress najpierw dołącza wtyczkę, a następnie wykonuje hak akcji plugins_loaded.

Najlepszą praktyką jest używanie haka akcji plugins_loadedzamiast tworzenia instancji z funkcji, ponieważ jeśli plik wtyczki jest zawarty w dowolnym miejscu (np. W innym pliku wtyczki), nowe wystąpienie klasy jest tworzone za każdym razem, gdy plik jest dołączany. Hak akcji plugins_loadedjest wykonywany tylko raz dla każdego żądania strony.

Ralf912
źródło
0

Może się zdarzyć, że przekażesz kopię swojej klasy do filtra lub akcji. Na przykład, jeśli chcesz bezpośrednio zmodyfikować zmienne klasy wewnątrz haka lub filtra, powinieneś również przekazać hak przez referencję

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

zamiast

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

Jak wspomniano w bainternet, możesz również użyć wzorca singletonu, aby upewnić się, że określony obiekt jest zaimplementowany tylko raz (kolejne wywołania zwracają odniesienie do tego obiektu).

Możesz również rozważyć ustawienie niektórych funkcji na statyczne (poprzez nadanie im słowa kluczowego static. Zwykle dzieje się to w przypadku funkcji pomocniczych, które nie wchodzą w interakcje z resztą klasy. Metody statyczne można wywoływać bez instancji klasy.

Możesz także przekazać funkcje statyczne do akcji / filtra:

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

Sprawdziłem również http://codex.wordpress.org/Plugin_API/Action_Reference i stwierdziłem, że wtyczki mogą być ładowane tylko w dwóch etapach żądania (muplugins_loaded i plugins_loaded).

Arevico
źródło
3
Gdy obiekt jest wysyłany przez argument, zwracany lub przypisywany do innej zmiennej, różne zmienne nie są aliasami: przechowują kopię identyfikatora, która wskazuje na ten sam obiekt. z podręcznika PHP . W wywołaniu akcji lub filtrze klasa jest wysyłana jako argument. Ponieważ PHP5 nie ma potrzeby przekazywania go jako odniesienia.
Ralf912
Poprawiłem się
Arevico,