プラグインライフサイクルのドキュメントはありますか?


11

プラグインのライフサイクルとは何かを説明するドキュメントがどこかにありますか?

私はOOPスタイルの新しいプラグインを開始しましたが、私のメインクラスが非常にインスタンス化されていることがわかりまし(XdebugとNetbeansのおかげです)。
Dropbox-APIオブジェクトをインスタンス化しているので、それが私をイライラさせ、WordPressがメインクラスをそれほどインスタンス化するとは思わなかったのです。

CodexでもGoogleでも、プラグインのライフサイクルに関連するものは見つかりませんでした。


そして、ここで、あなたはここで検索しましたか?:)
ブラソフィロ

20
YouPornは常にクラスをシングルトンとして定義できますstackoverflow.com/questions/203336/…–
Bainternet

1
ありがとう。「ベストプラクティス」については考えませんでした。コーディングガイドラインなど、コーデックスに関する多くのことを読みましたが、ここにはありません。シングルトンを試してみますが、それでも、プラグインphpが複数回呼び出されるのは奇妙です。Bainternetはオートコンプリートに注意してください:)
RitonLaJoie

brasofilo、シングルトンを作ることは助けにはなりますが、次の質問には答えません:なぜプラグイン内でコードが複数回実行されるのですか?リンクしたURLのOOクラスは、私がしていることとまったく同じことをしています
-RitonLaJoie

2
質問に+1する必要がありました。コメントと賛成のみ:D
kaiser

回答:


3

OOPスタイルで新しいプラグインを開始しています

「OOPスタイル」とはどういう意味ですか?すべての関数をクラスステートメントでラップしますか?その後、あなたはそれを間違ってやっています。クラスを名前空間として誤用しています。

そして私はちょうど私のクラスがたくさんインスタンス化されていることを知りました

え?

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

それを試して、作成されたファイルの数を数えてください。試してみると、各ページリクエストごとに1つのファイルが作成されます。つまり、各ページリクエストに対してFooクラスのインスタンスは1つだけです。

アクション呼び出しを試してみましょう

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 dirを見ると、2つのファイルが見つかりました。もういや。クラスインスタンスが作成されると、1つのファイルが作成されます。そして、アクションの呼び出しが完了すると作成されます。

OK、インスタンスを使用してバカなことをしましょう。を削除して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 );

いくつのファイルが必要ですか?2つ期待しています。1つはコンストラクターから、もう1つはメソッドから。

新しいインスタンスは、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 );

次に、4つのファイルをカウントします。コンストラクターから2つ、メソッドから2つ。これは、WordPressが最初にプラグインを組み込み、次にアクションフックを実行するためplugins_loadedです。

plugins_loadedプラグインファイルがどこか(プラグインの別のファイルなど)に含まれている場合、ファイルが含まれるたびにクラスの新しいインスタンスが作成されるため、ベストプラクティスは関数からインスタンスを作成する代わりにアクションフックを使用することです。アクションフックplugins_loadedは、ページリクエストごとに1回だけ実行されます。


0

何が起こるかは、クラスのコピーをフィルターまたはアクションに渡すことです。たとえば、フックまたはフィルター内のクラス変数を直接変更する場合は、参照によってフックも渡す必要があります

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

の代わりに

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

bainternetで述べられているように、特定のオブジェクトが1回だけインスタンス化されるようにシングルトンパターンを使用することもできます(それ以上の呼び出しはそのオブジェクトへの参照を返します)。

また、いくつかの関数を静的にすることを検討することもできます(静的キーワードを与えることにより、これは通常、クラスの他の部分と対話しない「ヘルパー」のような関数に対して行われます。静的メソッドは、クラスをインスタンス化せずに呼び出すことができます。

静的関数をアクション/フィルターに渡すこともできます。

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

また、http: //codex.wordpress.org/Plugin_API/Action_Referenceを確認したところ、プラグインはリクエストの2つの段階(muplugins_loadedとplugins_loaded)でしかロードできないことがわかりました。


3
オブジェクトが引数によって送信、返される、または別の変数に割り当てられるとき、異なる変数はエイリアスではありません。それらは同じオブジェクトを指す識別子のコピーを保持します。 PHPマニュアルから。アクションの呼び出しまたはフィルターでは、クラスは引数として送信されます。PHP5以降、参照として渡す必要はありません。
-Ralf912

私は修正された
Arevico
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.