WordPress插件更新时执行一次性数据库操作的合适Action是什么
WordPress自定义插件一次性更新任务的触发实现方案
WordPress核心没有提供能100%覆盖所有更新场景、仅在插件更新时触发的专用钩子,最稳妥、最适配你多站点自动更新全量推送场景的方案是版本号校验+轻量钩子挂载,完全可以解决你之前用plugins_loaded每次加载都执行业务逻辑的问题。
为什么不推荐网传的upgrader_process_complete钩子
这个钩子是WordPress更新流程完成时触发的原生钩子,但不适合你的使用场景:
- 触发场景受限:仅在通过后台、WP-CLI、自动更新走标准更新流程时才会触发,如果你手动替换插件文件、站点因为权限/缓存问题跳过更新流程回调,任务会直接漏跑
- 自动更新兼容性差:WordPress自动更新是走WP-Cron异步执行的,部分站点配置的另类缓存、定时任务偏移会导致钩子无法正常触发,全量推送时很容易出现部分站点没执行任务的问题
推荐实现方案
核心逻辑非常简单:在插件内硬编码当前版本号,将已执行任务的版本存入站点options表,每次插件加载时仅做极轻量的版本比对,仅当代码版本高于数据库存储的已执行版本时,才运行你预设的一次性任务,执行完成后更新数据库内的版本标记,后续所有请求都不会重复执行任务。
你可以直接把下面的代码放到自定义插件的主文件中使用:
// 自定义插件当前版本号,每次要推送新的一次性任务时,将版本号上调即可 define('MY_CUSTOM_PLUGIN_VER', '1.1.0'); add_action('plugins_loaded', 'my_custom_plugin_run_update_tasks'); function my_custom_plugin_run_update_tasks() { // 读取数据库中已执行过任务的版本标记 $executed_ver = get_option('my_custom_plugin_executed_ver', '0.0.0'); // 版本匹配则直接终止,无额外业务逻辑开销 if (version_compare($executed_ver, MY_CUSTOM_PLUGIN_VER, '>=')) { return; } // 以下区域放置你需要一次性执行的全量推送任务 // 示例1:禁用引发问题的第三方插件 require_once ABSPATH . 'wp-admin/includes/plugin.php'; deactivate_plugins('bad-plugin/bad-plugin.php'); // 示例2:清理失去访问权限的旧用户 // 在这里写你对应的用户筛选、降权/删除逻辑即可 // 所有任务执行完成后更新版本标记,避免重复执行 update_option('my_custom_plugin_executed_ver', MY_CUSTOM_PLUGIN_VER); }
方案优势
- 无漏跑风险:不管是后台手动更新、自动更新、WP-CLI更新、直接手动替换插件文件,只要新代码加载到站点,任务就会精准执行一次
- 性能影响可忽略:每次请求仅做一次option读取和版本号比对,option查询默认会被WordPress对象缓存接管,额外开销不到0.1ms,远低于直接在
plugins_loaded挂载业务逻辑的性能消耗 - 易排查:你可以直接通过查询数据库中
my_custom_plugin_executed_ver的option值,快速判断对应站点是否已经执行了你推送的任务
注意:如果你要执行的是大批量用户清理、数据库表结构变更这类耗时较长的操作,不要在上述逻辑中直接运行耗时任务,可以在版本校验通过后,向WP-Cron投递一个异步任务在后台静默执行,避免影响前端访客的正常访问。
内容的提问来源于stack exchange,提问作者dovidev
相关产品推荐
相关产品推荐

