是否有一些文档可以解释插件的生命周期?
我正在启动一个具有OOP风格的新插件,但我发现我的主类实例化了很多(这要归功于Xdebug和Netbeans)。
我不知道为什么,这让我很烦,因为我要实例化一个Dropbox-API对象,而且我真的不认为WordPress可以这么多地实例化我的主类。
我在Codex和Google上都没有发现任何与插件生命周期相关的信息。
是否有一些文档可以解释插件的生命周期?
我正在启动一个具有OOP风格的新插件,但我发现我的主类实例化了很多(这要归功于Xdebug和Netbeans)。
我不知道为什么,这让我很烦,因为我要实例化一个Dropbox-API对象,而且我真的不认为WordPress可以这么多地实例化我的主类。
我在Codex和Google上都没有发现任何与插件生命周期相关的信息。
Answers:
我正在开始使用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
每个页面请求仅执行一次动作挂钩。
可能发生的是,您将类的副本传递给过滤器或操作。例如,如果您想直接在挂钩或过滤器中修改类变量,则还应通过引用传递挂钩
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)。