WordPress插件捕获激活事件时error_log为空问题
问题根因
激活回调不触发、日志无输出的核心问题是**register_activation_hook注册时机过晚**:
- WordPress插件激活流程的执行顺序是:用户点击激活按钮 → 加载插件主文件 → 处理已注册的激活钩子 → 执行激活回调 → 后续流程才会触发
init钩子。你把激活钩子的注册逻辑放在了init的回调函数里,等代码跑到注册步骤时,激活事件早就执行完毕,自然不会触发你写的activate方法,也不会产生任何日志。 - 隐藏坑点:
register_activation_hook第一个参数要求传入插件主文件(即存放插件头注释的根文件)的绝对路径,如果你当前的类代码写在插件的子引入文件中,直接使用__FILE__会拿到子文件路径,就算注册时机正确也会导致钩子失效。
修复代码
不要在任何动作钩子里包裹激活钩子的注册逻辑,直接在插件全局加载阶段调用注册函数即可,参考修正后的代码:
class International_Law { public static function init_actions() { // 这里放常规初始化逻辑,比如注册自定义文章类型、添加路由、挂载admin_init等普通钩子 } public static function activate(){ error_log("插件激活成功触发"); // 建表逻辑请使用WordPress官方提供的dbDelta函数,避免表已存在时报错、字段更新不兼容问题 global $wpdb; $table_name = $wpdb->prefix . 'international_law'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, -- 按需补充你的业务表字段 create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) $charset_collate;"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta( $sql ); } } // 直接在全局范围注册激活钩子,不要嵌套在其他钩子回调内 // 若当前代码不在插件主文件,__FILE__需要替换为插件主文件路径,例如主文件为根目录下international-law.php时,可写为 plugin_dir_path( __DIR__ ) . 'international-law.php' register_activation_hook( __FILE__, array( 'International_Law', 'activate' ) ); // init钩子仅挂载常规初始化逻辑 add_action( 'init', array( 'International_Law', 'init_actions' ) );
调试注意
调试前请先在wp-config.php中开启WordPress调试开关,确保日志可以正常写入:
define( 'WP_DEBUG', true ); define( 'WP_DEBUG_LOG', true ); define( 'WP_DEBUG_DISPLAY', false );
修改代码后先停用插件再重新激活,即可在wp-content/debug.log中看到对应输出。
内容的提问来源于stack exchange,提问作者Kifsif
相关产品推荐
相关产品推荐

