使用插件API的筛选器和操作?

时间:2015-04-19 作者:Philipp

我想将公共API集成到我开发的插件中。

其他插件集成API的通常方式是定义一些可由任何主题或插件调用的函数。

然而,我认为这是一个坏主意,因为当我的API插件不活动时,它会导致错误,我想到了为API使用过滤器和操作的想法。就像这样:

// Get some user specific data from my plugin:
$data = false;
if ( apply_filters( \'mp:is-active\' ) ) {
    $data = apply_filters( \'mp:get-user-data\' );
}

// Add a private notification for a single user:
do_action( \'mp:send-notification\', $user_id, $message );
问题是:

我还从未在其他插件中见过这种API,所以有没有好的理由不使用它(例如性能不好等)

或者你认为这是一个好方法吗?

2 个回复
最合适的回答,由SO网友:gmazzap 整理而成

当然,这种方法有一些好处,但也有一些问题。

如果插件的目标是WordPress开发人员,他们会非常熟悉插件API,但最终用户并不熟悉。

对于非开发人员,类似于:

$data = give_me_the_data();
它比以下内容更容易理解、记忆和键入:

$data = apply_filters( \'give_me_the_data\' );
如果你看看这个网站上的一些问题,你就会明白新手和非开发人员对WordPress中的操作和过滤器有多困惑。

“拼写错误”问题作为一个经常拼写错误的人,我知道他们令人沮丧。如果您编写了一个有拼写错误的函数,它会抛出一个错误,用户会立即意识到这个问题。操作名称中的输入错误会导致API失败,但很难识别。

例如:

$data = apply_filters(\'mp:get-user-data\'); // works

$data = apply_filters(\'mo:get-user-data\'); // does not work, hard to find why

$data = mp_get_user_data(); // works

$data = mo_get_user_data(); // does not work and throws an error, immediately found
全局hell操作和过滤器只是全局变量。如果你用它们来构建你的API,你的代码可能会被系统中的任何一行代码所破坏。

这意味着,任何一个知道哪个插件的人身上的bug都会让你的插件无缘无故地失败。原因是你的插件不会失败。

示例:

do_action( \'mp:send-notification\', $user_id, $message );

// somewhere else
add_action( \'all\', \'do_something_bad_that_makes_your_plugin_fail\');
此外,任何人都可以使用这些钩子,即使它可以为您的API带来很多灵活性,也会带来很多复杂性。

例如,如果您使用对象作为参数,作为通过引用传递的对象,则它们可能在回调运行之前被修改。

结论这些都是我现在想到的原因,但如果这种方法没有得到广泛应用,可能还有其他原因。

对我来说,我不会使用这种方法,尤其是最后一点,但我不能说这在WordPress上下文中是绝对错误的。

因此,我不想强烈劝阻您使用它,只是建议您提前考虑所有问题,因为一旦您公开发布API,就很难切换。

SO网友:fuxia

这两种方法并非相互排斥。正如@gmazzap所说,不要创建回调地狱。

但是,您可以提供一个初始挂钩,这样其他开发人员就不必依赖速度相当慢的function_exists() 检查。

示例

在插件中,提供一个钩子,其他开发人员可以使用它安全地调用您的类和函数。

add_action( \'wp_loaded\', [new Your_Plugin_Bootstrap, \'setup\' ], 0 );

class Your_Plugin_Bootstrap {

    public function setup() {

        // set up your data and the auto-loader, then:
        do_action( \'your_plugin_loaded\' );
    }
}
现在,第三方开发人员可以使用该挂钩并继续使用“普通”PHP。

add_action( \'your_plugin_loaded\', function() {

    // safely use your plugin\'s classes here.
});
我们do that in MultilingualPress, 到目前为止,其他开发人员的反馈非常好。这很容易理解,你只需要学习一个钩子。

另请参见:How to create an API for my plugin?

结束