WordPress插件更新钩子绑定问题:upgrader系列钩子无效求助
WordPress插件更新时触发Webhook的问题排查与解决经验
我正在开发一款WordPress插件,想要在插件更新完成后发送Webhook。先后尝试绑定upgrader_post_install过滤器和upgrader_process_complete动作,但都没生效,日志里也没报错信息。
尝试的过滤器代码(upgrader_post_install)
// Webhook URL define('WEBHOOK_URL', 'https://example.com'); // Hook into the plugin update process add_filter('upgrader_post_install', 'webhook_on_plugin_update', 10, 3); function webhook_on_plugin_update($response, $hook_extra, $result) { // Check if the update process is for a plugin if ($hook_extra['type'] === 'plugin' && $hook_extra['action'] === 'update') { // Get the updated plugin information $plugin_info = $hook_extra['plugins'][0]; // Prepare data for the webhook payload $payload = array( 'event' => 'plugin_updated', 'plugin_name' => $plugin_info['Name'], 'plugin_version' => $plugin_info['Version'], 'timestamp' => current_time('timestamp'), ); // Send the webhook send_webhook_request($payload); } return $response; } function send_webhook_request($payload) { // Use wp_remote_post to send the webhook request wp_remote_post(WEBHOOK_URL, array( 'body' => json_encode($payload), 'headers' => array('Content-Type' => 'application/json'), )); }
尝试的动作代码(upgrader_process_complete)
define('WEBHOOK_URL', 'https://example.com'); add_action('upgrader_process_complete', 'webhook_on_plugin_update', 150); function webhook_on_plugin_update($upgrader_object, $options) { if ($options['type'] === 'plugin' && $options['action'] === 'update') { $plugin_info = get_plugin_data(WP_PLUGIN_DIR . '/' . $options['plugins'][0]); $payload = array( 'event' => 'plugin_updated', 'plugin_name' => $plugin_info['Name'], 'plugin_version' => $plugin_info['Version'], 'timestamp' => current_time('timestamp'), ); send_webhook_request($payload); } } function send_webhook_request($payload) { wp_remote_post(WEBHOOK_URL, array( 'body' => json_encode($payload), 'headers' => array('Content-Type' => 'application/json'), )); }
针对这两个钩子的使用经验与问题修复
1. upgrader_post_install 过滤器的注意点
这个钩子在插件安装/更新完成后触发,但存在几个易踩的坑:
- 参数与数据准确性:虽然代码中参数数量设置正确,但
$hook_extra['plugins'][0]在更新场景下可能只是插件的路径字符串,而非解析后的完整插件信息,无法直接获取Name和Version。 - 执行时机限制:钩子触发时新文件刚替换完成,但
$hook_extra的数据源来自更新前的请求,可能携带旧版本的插件信息,导致获取的数据不准确。
2. upgrader_process_complete 动作的正确用法
这个动作是更可靠的选择,它在整个升级流程完全结束后触发,但原代码需要调整几个关键点:
- 路径拼接问题:
WP_PLUGIN_DIR . '/' . $options['plugins'][0]可能出现重复斜杠,建议用trailingslashit(WP_PLUGIN_DIR) . $options['plugins'][0]避免路径错误。 - 函数依赖检查:
get_plugin_data属于后台函数,需确保文件已加载,添加函数存在性判断:if (!function_exists('get_plugin_data')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } - 优先级调整:原代码设置的优先级150过高,建议改为10或20,确保回调能被正常触发。
- 调试日志添加:在回调中加入日志输出,确认钩子是否触发:
可在error_log('upgrader_process_complete triggered: ' . print_r($options, true));wp-content/debug.log中查看输出,判断钩子是否生效。
3. Webhook发送的调试优化
即使钩子触发,Webhook也可能因网络、SSL验证等问题发送失败,需在发送函数中添加错误日志:
function send_webhook_request($payload) { $response = wp_remote_post(WEBHOOK_URL, array( 'body' => json_encode($payload), 'headers' => array('Content-Type' => 'application/json'), 'timeout' => 10, // 增加超时时间 'sslverify' => true, // 测试环境自签证书可临时设为false )); // 记录请求结果 if (is_wp_error($response)) { error_log('Webhook request failed: ' . $response->get_error_message()); } else { error_log('Webhook sent, response code: ' . wp_remote_retrieve_response_code($response)); } }
4. 最终修正后的upgrader_process_complete代码示例
define('WEBHOOK_URL', 'https://example.com'); add_action('upgrader_process_complete', 'webhook_on_plugin_update', 10, 2); // 明确指定参数数量 function webhook_on_plugin_update($upgrader_object, $options) { // 仅处理插件更新动作 if ($options['type'] !== 'plugin' || $options['action'] !== 'update') { return; } // 确保get_plugin_data函数可用 if (!function_exists('get_plugin_data')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } // 遍历更新的插件(支持批量更新) foreach ($options['plugins'] as $plugin_path) { $plugin_file_path = trailingslashit(WP_PLUGIN_DIR) . $plugin_path; if (!file_exists($plugin_file_path)) { error_log('Plugin file not found: ' . $plugin_file_path); continue; } $plugin_info = get_plugin_data($plugin_file_path); $payload = array( 'event' => 'plugin_updated', 'plugin_name' => $plugin_info['Name'], 'plugin_version' => $plugin_info['Version'], 'plugin_slug' => dirname($plugin_path), // 可选:添加插件slug 'timestamp' => current_time('timestamp'), ); send_webhook_request($payload); } } function send_webhook_request($payload) { $response = wp_remote_post(WEBHOOK_URL, array( 'body' => json_encode($payload), 'headers' => array('Content-Type' => 'application/json'), 'timeout' => 10, )); if (is_wp_error($response)) { error_log('Webhook failed: ' . $response->get_error_message()); } else { error_log('Webhook sent successfully, code: ' . wp_remote_retrieve_response_code($response)); } }
内容的提问来源于stack exchange,提问作者Eoin H
相关产品推荐
相关产品推荐

