是否有插件生命周期文档?


11

是否有一些文档可以解释插件的生命周期?

我正在启动一个具有OOP风格的新插件,但我发现我的主类实例化了很多(这要归功于Xdebug和Netbeans)。
我不知道为什么,这让我很烦,因为我要实例化一个Dropbox-API对象,而且我真的不认为WordPress可以这么多地实例化我的主类。

我在Codex和Google上都没有发现任何与插件生命周期相关的信息。


在这里,您在这里搜索过吗?:)
brasofilo 2012年

20
-超总是可以定义你的类作为一个单身stackoverflow.com/questions/203336/...
Bainternet

1
谢谢。我没想到过“最佳实践”。我在Codex上阅读了很多内容,包括《编码指南》,但它不在这里。Bainternet小心您的自动完成功能:)
RitonLaJoie 2012年

brasofilo,创建一个单例会有所帮助,但不能回答以下问题:为什么代码在我的插件中多次运行?您链接的URL中的OO类完全按照我的方式做
RitonLaJoie 2012年

2
只需+1这个问题。仅用于评论和投票:D
kaiser

Answers:


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

尝试一下并计算创建的文件数。如果我尝试一下,则为每个页面请求创建一个文件。这意味着每个页面请求只有一个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每个页面请求仅执行一次动作挂钩。


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


3
当对象通过参数发送,返回或分配给另一个变量时,不同的变量不是别名:它们持有标识符的副本,该副本指向同一对象。 来自PHP手册。在动作调用或过滤器中,将类作为参数发送。从PHP5开始,无需将其作为参考传递。
Ralf912 2013年

我的立场是正确的
Arevico
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.