问题描述

我正在开发插件,我有一个关于 best practices 和约定的问题。

我需要的 ?

我的插件将存储一些预定义对象,对象列表 (或只是数组/key-value 对),并且可以添加新对象并填充其字段。例如我的对象将具有以下内容

{
  "id": 123,
  "url": "http://google.com/",
  "enabled" : true,
  "name": "hello_world",
  "api_key" : "api_key"
}

简单的 JSON 对象。

而在 Plugin Admin configuration page 上,可以添加,编辑或删除这些对象。

我的问题是什么?

存储此类数据的最佳方式是什么?我已经安装了很多不同的插件,以便了解如何存储设置中的自定义数据。有一些我看过的选择

  1. 使用 WordPress 提供的 Settings API 。即使 UI 由 wordpress 处理,您只需调用该函数即可创建正确的输入字段,并将所有设置保存到选项表中。所有支票和安全性也由 wordpress 处理。但是可以创建动态管理页面,您可以在其中添加新项目吗?

  2. 使用旧的 Options API 也存储在选项表中,但给开发人员更多的自由来处理所有的验证。

  3. 创建新的数据库表并保存数据。

我不认为我会使用第三种方法。

请建议更好的方法来做到这一点,也许你知道插件已经以正确的方式实现了这样的功能。我会感谢任何帮助。

最佳解决方案

这取决于你将如何使用存储的数据。

如果要针对值运行复杂查询,请使用针对这些查询优化的索引的自定义表。

如果您将始终只获取给定对象的所有值,请创建一个 non-public 自定义帖子类型,并将数据存储为后期元数据。

不要将数据存储在序列化的字符串中,就像选项 API 一样。当您要根据命令行 SQL 更改它时,这是一个噩梦,因为序列化格式是特定于 PHP 的。

“Settings API” 提供了一些非常过时的标记,注册和存储的代码是 counter-intuitive 。我不建议使用它。

次佳解决方案

Where to store plugin settings fields?

选项表 FTW 。它被缓存并且易于做 CRUD 。

Settings API or Options API?

基本上,您可以在没有设置 API 的情况下使用 use Options API,但不能使用选项 API 的 use Settings API 。即使您只需要向现有的 WordPress 页面添加一些字段,您仍然需要 get_option()来检索视图模板的数据。

但是通过使用现有的 WordPress 页面,您的数据将被分段,难以检索/维护,因为它与不同的 option_name 存储。也可能会混淆 end-users 。

当仅使用 Options API 时,作为插件的作者,您可以随时添加新闻部分/字段,但其他人不能添加。因为视图模板是硬编码的,没有像 do_settings_sections()do_settings_fields()一样工作的钩子。当然,您可以使用 do_action(),但会更复杂。

使用选项 API 给开发人员更多的自由来处理所有验证是不正确的。设置 API 具有 sanitize_callback,它还允许开发人员使用输入数据进行任何所需的操作。

那么为什么不使用他们呢?

例如,假设使用 Settings API 和 Options API 与 option_group 的设置页面是 my_app_groupoption_namemy_app

$options = get_option('my_app');

?><div class="wrap">
    <h1><?= __('Plugin Settings', 'textdomain') ?></h1>
    <form class="form-table" method="post" action="options.php">
        <?php settings_fields('my_app_group') ?>
        <table>
            <tr>
                <td>
                    <label for="my_app[name]">
                        <?= __('App Name', 'textdomain') ?>
                    </label>
                </td>
                <td>
                    <input type="text" name="my_app[name]" value="<?= $options['name'] ?>">
                </td>
            </tr>
            <tr>
                <td>
                    <label for="my_app[app_key]">
                        <?= __('App Key', 'textdomain') ?>
                    </label>
                </td>
                <td>
                    <input type="text" name="my_app[app_key]" value="<?= $options['app_key'] ?>">
                </td>
            </tr>
            <?php do_settings_fields('my_app_group', 'default') ?>
        </table>
        <?php do_settings_sections('my_app_group') ?>
        <?php submit_button() ?>
    </form>
</div><?php

现在,所有数据都存储在 my_app 选项名称下的选项表中,因此很容易检索/维护。其他开发人员也可以为插件添加新的部分/字段。

参考文献

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