Есть ли документация по жизненному циклу плагина?

11

Где-нибудь есть документация, объясняющая, каков жизненный цикл плагинов?

Я запускаю новый плагин со стилем ООП, и я только что узнал, что мой основной класс часто создается (благодаря Xdebug и Netbeans).
Я удивляюсь, почему, и это раздражает меня, потому что я создаю экземпляр объекта Dropbox-API, и я действительно не думал, что WordPress просто так будет создавать мой основной класс.

Я не нашел ничего связанного с жизненным циклом плагинов ни в Кодексе, ни в Google.

RitonLaJoie
источник
И здесь, вы искали здесь ? :)
brasofilo
20
YouPorn всегда может определить ваш класс как singleton stackoverflow.com/questions/203336/…
Bainternet
1
Благодарю. Я не думал о «лучших практиках». Я много читал о Кодексе, в том числе о правилах кодирования, но его здесь нет. Попробую синглтон тогда, но все же я нахожу странным, что плагин php вызывается несколько раз. Нет? Bainternet будь осторожен со своим автозаполнением :)
RitonLaJoie
brasofilo, создание синглтона поможет, но не отвечает на вопрос: почему код запускается несколько раз внутри моего плагина? Класс OO в URL-адресе, который вы
указали,
2
Просто должен был +1 вопрос. Только для комментариев и голосов: D
kaiser

Ответы:

3

Я запускаю новый плагин в стиле ООП

Что для вас значит «стиль ООП»? Обернуть все ваши функции оператором класса? Тогда вы делаете это неправильно. Вы пропускаете класс как пространство имен.

и я только что узнал, что мой основной класс часто создается

А?

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

Попробуйте и посчитайте количество созданных файлов. Если я попробую, то для каждого запроса страницы будет создан один файл. Это означает, что только один экземпляр класса Foo для каждого запроса страницы.

Давайте попробуем призыв к действию

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

Если я загляну в мой каталог wp-content, я найду два файла. Больше не надо. Один файл создается при создании экземпляра класса. И один создается, когда вызов действия сделан.

Хорошо, давайте сделаем некоторые глупости с нашим экземпляром. Удалите add_action( 'plugins_loaded', .. )и добавьте этот код:

function bar( $foo ) {

    $baz = $foo;
    return $baz;
}

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

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

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

Сколько файлов вы ожидаете? Я ожидаю два. Один из конструктора, один из метода.

Новый экземпляр создается только при использовании 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 );

Сейчас я считаю четыре файла. Два из конструктора и два из метода. Это потому, что WordPress сначала включает плагин, а затем выполняет действие plugins_loaded.

Рекомендуется использовать ловушку действия plugins_loadedвместо создания экземпляра из функции, потому что, если файл плагина включен где-либо (например, в другом файле вашего плагина), новый экземпляр класса создается каждый раз, когда файл включается. Хук действия plugins_loadedвыполняется только один раз для каждого запроса страницы.

Ralf912
источник
0

Может случиться так, что вы передадите копию своего класса фильтру или действию. Например, если вы хотите напрямую изменить переменные класса внутри ловушки или фильтра, вы также должны передать ловушку по ссылке

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

вместо того

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

Как уже упоминалось в bainternet, вы также можете использовать одноэлементный шаблон, чтобы убедиться, что конкретный объект создается только один раз (дальнейшие вызовы возвращают ссылку на этот объект).

Вы также можете подумать о том, чтобы сделать некоторые функции статичными (назначив им ключевое слово static. Обычно это делается для функций типа «помощник», которые не взаимодействуют с остальной частью класса. Статические методы можно вызывать без создания экземпляра класса.

Вы также можете передать статические функции в действие / фильтр:

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

Я также проверил http://codex.wordpress.org/Plugin_API/Action_Reference и обнаружил, что плагины могут быть загружены только в два этапа запроса (muplugins_loaded и plugins_loaded).

Arevico
источник
3
Когда объект отправляется с помощью аргумента, возвращается или присваивается другой переменной, различные переменные не являются псевдонимами: они содержат копию идентификатора, который указывает на тот же объект. из руководства по PHP . При вызове действия или фильтре класс отправляется в качестве аргумента. Начиная с PHP5 нет необходимости передавать его как ссылку.
Ralf912,
Я исправлен
Аревико