问题描述

启动社区 wiki 来收集插件开发的客观最佳实践。这个问题是由 @EAMann’s comments on wp-hackers 启发的。

这个想法是协调一些客观的最佳实践,以便我们最终可以在一些社区协作审核过程中使用它们。

更新:在看到前几个答复之后,很明显,我们只需要有一个想法/建议/ best-practice 每个答案,人们应该查看列表,以确保在发布之前没有重复。

最佳解决方案

 Use Actions and Filters

如果您认为人们想添加或更改某些数据:在返回之前提供 apply_filters()

P.S. One thing I find a bit disappointing and that your question addresses is the percentage of plugins that are designed only for end-users, i.e. that have no hooks of their own. Imagine if WordPress were designed like most plugins? It would be inflexible and a very niche solution.

Maybe things would be different if WordPress were to have the ability to auto-install plugins on which other plugins depended? As it is I typically have to write a lot of the functionality I need from scratch because clients want things a certain way and the available plugins, while 90% there, don’t allow me the flexibility to update the remaining 10%.

I really do wish those leading the WordPress community would identify a way to ensure that plugins are rewarded for following best practices (such as adding in hooks for other developers) much like good answers are rewarded on a StackExchange site.

another question 为例:

Example: I want to do something in my plugin when someone retweets an article. If there was a custom hook in whatever the popular retweet plugin is that I could hook in to and fire off of, that would be great. There isn’t, so I can modify their plugin to include it, but that only works for my copy, and I don’t want to try to redistribute that.

Related

次佳解决方案

使用 wp_enqueue_scriptwp_enqueue_style 加载脚本/ CSS

插件不应加载/尝试加载 JS / CSS 文件的重复版本,尤其是 WP Core 中包含的 jQuery 和其他 JS 文件。

在连接 JS 和 CSS 文件时,插件应始终使用 wp_enqueue_scriptwp_enqueue_style,而不要直接通过<script> 标签。

Related

第三种解决方案

I18n 支持

所有输出字符串都应链接到适当的文本域,以便有兴趣的方面进行国际化,即使开发人员没有兴趣翻译自己的 plug-in 。

请注意,在 init 操作期间加载语言文件非常重要,因此用户可以挂接到该操作中。

见食典:I18n for WordPress Developers

还有这篇文章:Loading WP language files the right way 。其结论如下:

[…]
Finally, I would like to point out that is important to load custom user language files from WP_LANG_DIR before you load the language files that ship with the plugin. When multiple mo-files are loaded for the same domain, the first found translation will be used. This way the language files provided by the plugin will serve as a fallback for strings not translated by the user.

public function load_plugin_textdomain()
{
    $domain = 'my-plugin';
    // The "plugin_locale" filter is also used in load_plugin_textdomain()
    $locale = apply_filters( 'plugin_locale', get_locale(), $domain );

    load_textdomain(
            $domain,
            WP_LANG_DIR . '/my-plugin/' . $domain . '-' . $locale . '.mo'
    );
    load_plugin_textdomain(
            $domain,
            FALSE,
            dirname( plugin_basename(__FILE__) ) . '/languages/'
    );
}

第四种方案

确保插件使用 WP_DEBUG 生成无错误

始终使用 WP_DEBUG 测试您的插件,并在开发过程中理想地启用它。插件不应该在 WP_DEBUG 上抛出任何错误。这包括已弃用的通知和未检查的索引。

要打开调试开关,请编辑 wp-config.php 文件,使 WP_DEBUG 常数设置为 true 。有关详细信息,请参阅调试法典。

第五种方案

首先在 WordPress 核心中使用现有的功能

如果可以:使用 WordPress 核心中的现有功能,而不是编写自己的。只有在 WordPress 核心中没有适当的 pre-existing 功能时才开发定制的 PHP 功能。

一个好处是您可以使用 “日志已弃用的通知” 来轻松监控应该替换的功能。另一个好处是用户可以在 Codex 中查看功能文档,并更好地了解插件的功能,即使他们不是经验丰富的 PHP 开发人员。

Related

第六种方案

使用输入数据防止 SQL 注入

在使用输入值查询 MySQL 数据库之前,插件应清理直接或间接检索的所有用户输入 (例如通过 $_POST$_GET) 。

参见:Formatting SQL statements

第七种方案

卸载应该删除所有插件的数据

从 WordPress 安装中删除后,插件应删除其创建的所有文件,文件夹,数据库条目和表以及其创建的选项值。

插件可能提供导出/导入设置的选项,以便在删除之前可以将设置保存在 WordPress 之外。

Related

第八种方案

前缀所有全局命名空间项

一个插件应该适当地前缀所有全局命名空间项 (常量,函数,类,变量,甚至诸如自定义分类法,帖子类型,小工具等) 。例如,不要创建一个名为 init()的函数; 而是将其命名为 jpb_init()

它的共同点应该是在名称前面使用三个或四个字母的前缀,或者使用 PHP Namespace Feature 。比较:Single-letter prefix for PHP class constants?

Related

第九种方案

使用类和面向对象的 PHP5 代码

没有理由不写干净的 object-orientated PHP5 代码。 PHP4 的支持将在下一个版本 (WP 3.1) 之后逐步淘汰。当然,你可以把所有的函数名称前缀到 finallyly_long_function_names_with_lots_of_underscores,但是编写一个简单的类并且捆绑所有的东西要容易得多。此外,将您的课程放在一个单独的文件中,并相应地命名,以便您可以轻松地扩展和维护它:

// in functions.php
require 'inc/class-my-cool-plugin.php';
new MyCoolPlugin();

// in inc/class-my-cool-plugin.php
class MyCoolPlugin {
    function __construct() {
        // add filter hooks, wp_enqueue_script, etc.

        // To assign a method from your class to a WP
        // function do something like this
        add_action('admin_menu', array($this, "admin"));
    }

    public function admin() {
        // public methods, for use outside of the class
        // Note that methods used in other WP functions
        // (such as add_action) should be public
    }

    private function somethingelse() {
        // methods you only use inside this class
    }
}

第十种方案

停用不应该引起 Data-Loss

停用时,插件不应删除任何数据。

Related

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。