wordpress插件_WordPress插件以正确的方式更新

wordpress插件

Some weeks ago, I received an email about WP Photo Sphere, a WordPress plugin I developed. There was a big problem: updating the plugin broke it on some installations. After some investigation, I discovered that the problem came from the options used by the plugin: these installations hadn’t any default values for the new options I added.

几周前,我收到了一封有关我开发的WordPress插件WP Photo Sphere的电子邮件。 有一个大问题:更新插件在某些安装中使它损坏。 经过一番调查,我发现问题出在插件使用的选项上:这些安装对我添加的新选项没有任何默认值。

WordPress Plugin Updates

These values were important, so I needed a way to create the default values. But, contrary to what I thought, WordPress doesn’t provide any native way to handle an update process.

这些值很重要,因此我需要一种创建默认值的方法。 但是,与我的想法相反,WordPress没有提供任何本地方法来处理更新过程。

That’s why I thought of writing this tutorial. First, we’ll see exactly why we need an update process and why WordPress doesn’t provide such a process. Then I’ll show you how to properly create your own process to update your options.

这就是为什么我想到编写本教程的原因。 首先,我们将确切了解为什么我们需要更新过程以及WordPress为什么不提供这种过程。 然后,我将向您展示如何正确创建自己的流程来更新您的选项。

为什么插件的更新过程很重要 (Why an Update Process for Your Plugin Is Important)

Often, changing files is not enough to properly update something. For example, when you manually update the WordPress files to a new version, the platform will ask you to hit a button to update the database too.

通常,更改文件不足以正确更新某些内容。 例如,当您手动将WordPress文件更新为新版本时,平台将要求您也单击按钮来更新数据库。

Assume that you use options in your plugin. As your plugin evolves, you’ll need more options in new versions. Creating new options when a user activates your plugin for the first time is easy, you just have to use the activation hook.

假设您在插件中使用了选项。 随着插件的发展,新版本将需要更多选项。 用户首次激活插件时创建新选项很容易,您只需要使用激活钩即可。

For example, let’s look at the following code.

例如,让我们看下面的代码。

function my_awesome_plugin_activation() {
    update_option('my_awesome_plugin_option', 'default value');
}
register_activation_hook(__FILE__, 'my_awesome_plugin_activation');

If you’re unfamiliar with using update_option() instead of add_option(), don’t worry, we’ll explain it later, when we’ll look at how to handle our update process.

如果您不熟悉使用update_option()而不是add_option() ,请放心,我们将在稍后讨论如何处理更新过程时再进行解释。

If you want a new option, or if you update the value of an existing option in a new version, you need to update the database of users who already use your plugin, so we need a function called right after the update.

如果要使用新选项,或者在新版本中更新现有选项的值,则需要更新已经使用插件的用户数据库,因此我们需要在更新后立即调用的函数。

The activation hook can seem a bit confusing. After all, when you automatically update a plugin, it is deactivated and reactivated, so we could expect this hook to be called. But it’s not the case.

激活挂钩似乎有些混乱。 毕竟,当您自动更新插件时,它会被停用并重新激活,因此我们可以期望这个钩子被调用。 但事实并非如此。

To be more precise, it was, but WordPress stopped this behavior in version 3.1. The development team explained this choice, and you can read the entire explanation on the Make WordPress Core blog. The main reason is that it wasn’t called every time is that if a user manually updates a plugin, the activation hook can be skipped.

确切地说,是的,但是WordPress在3.1版中停止了此行为。 开发团队解释了这种选择,您可以在Make WordPress Core博客上阅读整个解释。 主要原因不是每次都调用它是因为如果用户手动更新插件,则可以跳过激活挂钩。

So WordPress doesn’t provide a default way to automatically call a function right after a plugin update. That’s why you’ll need to build your own process.

因此,WordPress没有提供在插件更新后立即自动调用函数的默认方法。 这就是为什么您需要构建自己的流程的原因。

如何处理更新过程 (How To Handle an Update Process)

In this part of the tutorial I’ll show you how to automatically call a given function right after an update of your plugin. We’ll see in the next part how to properly handle the updates of existing options, and the creation of new ones (in the same function).

在本教程的这一部分中,我将向您展示如何在插件更新后立即自动调用给定函数。 在下一部分中,我们将看到如何正确处理现有选项的更新以及新选项的创建(在同一函数中)。

这种方法的原理 (The Principle of this Method)

The global principle of our method will be that we’ll store the version number of our plugin in two places: in a constant in the main file of the plugin, and in an option in the database.

该方法的全局原则是,我们将插件的版本号存储在两个位置:插件主文件中的常量以及数据库中的选项。

The number in the database will store the version currently installed by the user, while the number in the constant is the current version. If these two numbers are different, then the database options have not been updated since the last plugin update, so we’ll need to do it.

数据库中的数字将存储用户当前安装的版本,而常量中的数字为当前版本。 如果这两个数字不同,则自上次插件更新以来数据库选项尚未更新,因此我们需要这样做。

In this case, we call a function that updates all the necessary options. This function also updates the version number stored in the database: that way, we won’t call this function more than necessary.

在这种情况下,我们调用一个更新所有必要选项的函数。 此函数还会更新存储在数据库中的版本号:这样,我们将不会在不必要的情况下调用此函数。

常数 (The Constant)

Now that we’ve covered what we’ll do, it’s time to code! First, add a constant definition in the main file of your plugin, with your current version number as a value. In order to prevent any problems, we test if it does not exit yet.

既然我们已经介绍了我们将要做的事情,那么该开始编写代码了! 首先,在插件的主文件中添加一个常量定义,并将当前版本号作为值。 为了防止出现任何问题,我们测试它是否还没有退出。

if (!defined('MY_AWESOME_PLUGIN_VERSION'))
    define('MY_AWESOME_PLUGIN_VERSION', '3.4.1');

Usually, plugin versions are identified with numbers but, if you use another system, feel free to use it. The only constraint here is to have a unique identifier for each version or, at least, for each version which requires changes in the database (new options, new default values, etc.).

通常,插件版本用数字标识,但是,如果您使用其他系统,请随时使用。 这里唯一的限制是每个版本或至少每个版本都有唯一的标识符,这需要数据库中的更改(新选项,新的默认值等)。

检查功能 (The Checking Function)

We need now to write a function that will check if the database needs to be updated. This function will compare the previously defined constant with the value currently stored in the database. To do that, we’ll make sure that our function is called everywhere, with the action plugins_loaded, triggered once all the plugins are loaded.

现在,我们需要编写一个函数来检查是否需要更新数据库。 此函数会将先前定义的常数与当前存储在数据库中的值进行比较。 为此,我们将确保在所有位置都调用我们的函数,并在所有插件加载后触发动作plugins_loaded

function my_awesome_plugin_check_version() {
}

add_action('plugins_loaded', 'my_awesome_plugin_check_version');

This function will be simple. We retrieve the version number stored in the database, as any other option, and we compare it to the constant. If these values are different, we call the my_awesome_plugin_activation() function.

此功能将很简单。 与其他任何选项一样,我们检索存储在数据库中的版本号,并将其与常量进行比较。 如果这些值不同,我们将调用my_awesome_plugin_activation()函数。

if (MY_AWESOME_PLUGIN_VERSION !== get_option('my_awesome_plugin_version'))
    my_awesome_plugin_activation();

Now, there are some questions we need to clarify. First, what if the option doesn’t exist in the database yet? If the option doesn’t exist, get_option() returns false, which is different from your version number, so the function will be called.

现在,我们需要澄清一些问题。 首先,如果数据库中尚不存在该选项怎么办? 如果该选项不存在,则get_option()返回false ,它与您的版本号不同,因此将调用该函数。

So why do we call the activation function? To be clear, we could create a new function, dedicated to the update process. But, if you do this, you’ll see that this new function will be very similar to activation, as updating an option can be achieved the same way we create one.

那么为什么我们要调用激活功能呢? 需要明确的是,我们可以创建一个专门用于更新过程的新功能。 但是,如果执行此操作,您会发现此新功能将与激活非常相似,因为可以通过与创建选项相同的方式来实现对选项的更新。

更新数据库中的版本号 (Updating the Version Number in the Database)

You can do whatever you want in the activation function called above. However, there is one thing needed, updating the version number stored in the database. That way, we won’t call our function every time a page is loaded.

您可以在上述调用的激活函数中执行任何所需的操作。 但是,需要做一件事,更新存储在数据库中的版本号。 这样,我们不会在每次页面加载时都调用我们的函数。

update_option('my_awesome_plugin_version', MY_AWESOME_PLUGIN_VERSION);

Note the trick: we don’t use add_option(), just update_option(). In fact, if the option does not exist yet, update_option() will create it. If it exists, it will update its value to the indicated one. That’s why we can use our activation function as an update function without any problem.

请注意技巧:我们不使用add_option() ,而仅使用update_option() 。 实际上,如果该选项尚不存在,则update_option()将创建它。 如果存在,它将其值更新为指示的值。 因此,我们可以毫无问题地将激活功能用作更新功能。

更新选项 (Updating Options)

不要超越用户的选择! (Don’t Override Users’ Choices!)

Updating any option can be done the same way we updated the version number: you call update_option(), and you’re done, even if it’s the first time WordPress sees the option.

可以通过更新版本号的相同方法来更新任何选项:您调用update_option() ,就算完成了,即使这是WordPress第一次看到该选项。

However, we don’t always want to update the options values. In fact, if you use options, it’s often for letting your users personalize settings. By using update_option() you’ll override the users’ choices every time you update the plugin, which is not what we want to do.

但是,我们并不总是希望更新选项值。 实际上,如果使用选项,通常是让用户个性化设置。 通过使用update_option()您将在每次更新插件时覆盖用户的选择,这不是我们想要做的。

Above, we saw that get_option() returns false if the option doesn’t exist. We’ll use this behavior to test if the option we want to update exists in the database. If this is the case, we don’t do anything. Otherwise, we create the option.

上面,我们看到如果该选项不存在,则get_option()返回false 。 我们将使用此行为来测试数据库中是否存在我们要更新的选项。 在这种情况下,我们什么也不做。 否则,我们将创建该选项。

if (get_option('my_awesome_option') === false)
    update_option('my_awesome_option', 'my_value');

Note that this test is necessary for options you don’t want to override. In some cases, we might want to do this, think about the version number, where we surely don’t want to keep the old value!

请注意,对于您不想覆盖的选项,此测试是必需的。 在某些情况下,我们可能想这样做,想一想版本号,我们肯定不想保留旧值!

特例-阵列 (A Special Case – Arrays)

You should know that WordPress allows arrays to store values for our options, and creating them is not any more difficult that creating other options. For example:

您应该知道WordPress允许数组存储我们选项的值,创建它们并不比创建其他选项困难。 例如:

update_option('my_awesome_plugin_settings', array(
    'awesome_titles' => true,
    'any_number' => 7
));

Using arrays is a good idea if you need several settings. That way, you don’t use a lot of entries in the database, and you limit the chances to have an option with the same name used by another plugin. However, this can cause issues when we think about the update process.

如果需要几个设置,使用数组是一个好主意。 这样,您就不会在数据库中使用很多条目,并且限制了拥有与其他插件使用相同名称的选项的机会。 但是,当我们考虑更新过程时,这可能会导致问题。

To understand why, assume that you have an array as an option, with some keys. Your users will surely personalize these values. With the test we did above, we can create the option only if it does not exist, and these choices won’t be overridden. It seems straightforward, but what if you want to create a new key in your array?

要理解为什么,请假设您有一个带有一些键的数组作为选项。 您的用户肯定会个性化这些值。 通过上面的测试,我们可以仅在不存在该选项的情况下创建该选项,并且不会覆盖这些选择。 看起来很简单,但是如果要在数组中创建新键怎么办?

If the option exists in the database, the previous code won’t create it, so your new key won’t exist. But if we erase the condition, the array will retrieve its default values with each new update. Not ideal. Fortunately, there’s a solution!

如果该选项存在于数据库中,则先前的代码将不会创建该选项,因此您的新密钥将不存在。 但是,如果我们删除该条件,则该数组将在每次新更新时检索其默认值。 不理想。 幸运的是,有一个解决方案!

First, we define an array containing the default values of our options (with the new keys if they exist).

首先,我们定义一个包含选项默认值的数组(如果存在新键,则包含它们)。

$default = array(
    'awesome_title' => true,
    'any_number' => 7,
    'new_option' => 'default'
)

Then, we retrieve the array currently stored in the database.

然后,我们检索当前存储在数据库中的数组。

$option = get_option('my_awesome_plugin_settings');

Now we can use the PHP function array_merge(), with our default values array as the first parameter, and the user’s values array as the second one. That way, we’ll get an array containing all of the keys defined in the $default array and we won’t have any non-existing options. If the user has changed one of the old options, their values will be kept. With array_merge() we always keep the latest definition.

现在,我们可以使用PHP函数array_merge() ,将默认值数组作为第一个参数,将用户的values数组作为第二个参数。 这样,我们将获得一个包含$default数组中定义的所有键的数组,并且不会有任何不存在的选项。 如果用户更改了旧选项之一,则将保留其值。 使用array_merge()我们始终保留最新的定义。

$option_to_store = array_merge($default, $option);

Finally, we store the result in the database with update_option().

最后,我们使用update_option()将结果存储在数据库中。

update_option('my_awesome_plugin_settings', $option_to_store);

We’re close to the end, but we now need to fix a bug that you can run into if the function is executed for the very first time.

我们即将结束,但是现在我们需要修复一个bug,如果该函数是首次执行的,则可能会遇到该错误。

This function is called when the plugin is activated, that’s what we want. But, in this case, the option does not exist yet, so get_option() returns false. The problem is that using false as a parameter for array_merge() will cause an error.

激活插件后即调用此函数,这就是我们想要的。 但是,在这种情况下,该选项尚不存在,因此get_option()返回false 。 问题在于,使用false作为array_merge()的参数将导致错误。

What we want is simple, if the option doesn’t exist, we want $option to be an empty array. For that, we can use the second parameter of get_option() which represents the default value to get (in order to not return false).

我们想要的很简单,如果该选项不存在,我们希望$option是一个空数组。 为此,我们可以使用get_option()的第二个参数,该参数表示要获取的默认值(为了不返回false )。

$option = get_option('my_awesome_plugin_settings', array());

结论 (Conclusion)

Once you’ve gone over it, handling the update process for a WordPress plugin is not overly complicated. However, it’s important if you use options, since not initializing options can cause some problems.

一旦解决了它,处理WordPress插件的更新过程就不会太复杂。 但是,使用选项非常重要,因为不初始化选项可能会导致一些问题。

Currently, WordPress doesn’t provide a native way to handling plugin updates. The fact is, considering the problems we listed above, if we see this type of feature introduced one day, it should be implemented in a similar way to this tutorial.

当前,WordPress还没有提供处理插件更新的本地方法。 事实是,考虑到上面列出的问题,如果有一天我们看到了这种功能,则应该以与本教程类似的方式来实现。

You can get the code for my example plugin here. Treat this code as a skeleton for you to implement your own WordPress plugin update process. If you have any feedback, please let me know in the comments below.

您可以在此处获取示例插件的代码。 将此代码当作框架,以实现您自己的WordPress插件更新过程。 如果您有任何反馈意见,请在下面的评论中告诉我。

翻译自: https://www.sitepoint.com/wordpress-plugin-updates-right-way/

wordpress插件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值