開發 WordPress 主題/插件時,常需註冊自定義文章類型(CPT)及分類法。為保證數據整潔,插件停用/刪除時應清理相關數據:移除 CPT、分類法、自定義字段、選項表數據等。
register_deactivation_hook(__FILE__, 'my_plugin_deactivate'):插件停用時執行,適合清理暫存數據、刪除定時任務。register_uninstall_hook(__FILE__, 'my_plugin_uninstall'):插件刪除時執行,執行徹底清理(刪除 CPT 數據、選項、表)。<?php
// 插件主文件
register_deactivation_hook(__FILE__, 'my_plugin_deactivate');
register_uninstall_hook(__FILE__, 'my_plugin_uninstall');
// 停用:清理暫存、取消排程
function my_plugin_deactivate() {
// 刪除定時任務
wp_clear_scheduled_hook('my_plugin_cron_hook');
// 刷新重寫規則,避免 404
flush_rewrite_rules();
}
// 卸載:徹底清理數據
function my_plugin_uninstall() {
// 1. 刪除所有自定義文章類型文章
$posts = get_posts([
'post_type' => 'my_cpt',
'numberposts' => -1,
'post_status' => 'any',
'fields' => 'ids',
]);
foreach ($posts as $post_id) {
wp_delete_post($post_id, true); // true = 強制永久刪除,繞過垃圾桶
}
// 2. 刪除自定義分類法術語
$terms = get_terms(['taxonomy' => 'my_taxonomy', 'hide_empty' => false]);
foreach ($terms as $term) {
wp_delete_term($term->term_id, 'my_taxonomy');
}
// 3. 刪除選項表數據
delete_option('my_plugin_options');
delete_option('my_plugin_version');
delete_site_option('my_plugin_network_options'); // 多站點
// 4. 刪除用戶元數據
global $wpdb;
$wpdb->delete($wpdb->usermeta, ['meta_key' => 'my_plugin_meta']);
// 5. 刪除自定義表(如有)
// $wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}my_custom_table");
// 6. 刷新重寫規則
flush_rewrite_rules();
}
?>
get_posts 獲取 ID 後循環 wp_delete_post,避免一次性載入大量對象導致內存溢出。flush_rewrite_rules(),否則前台會出現 404。delete_site_option 清理網絡級選項。if (!current_user_can('activate_plugins')) return; 防止誤觸發。wp_posts、wp_terms、wp_options 相關數據是否乾淨。