WordPress插件调整PSR-4目录后触发call_user_func_array回调错误求助
问题分析与解决思路
错误核心原因
这个致命错误的本质是WordPress激活/停用钩子的回调无效,具体问题点:
- 激活钩子绑定了构造函数
__construct,这是错误用法——构造函数是实例化类时自动调用的,不能手动作为钩子回调 - 停用钩子绑定了实例方法
__deactivate,但插件停用过程中,之前创建的$onfmain实例可能已不可用,导致回调找不到有效对象 - 插件激活/停用的执行环境与正常加载不同,依赖实例的回调逻辑会失效
分步解决方案
1. 重构核心类的激活/停用逻辑
修改OnFeedMain.php,将激活/停用逻辑改为静态方法,避免依赖类实例:
namespace Oppimittinetworking\OnfeedFacebook; use Oppimittinetworking\OnfeedFacebook\Action\ONFActivate; use Oppimittinetworking\OnfeedFacebook\Action\ONFDeactivate; use Oppimittinetworking\OnfeedFacebook\RSA\ONFRSAEncrypt; use Oppimittinetworking\OnfeedFacebook\RSA\ONFRSADecrypt; class OnFeedMain { // 构造函数仅处理插件正常加载时的逻辑 public function __construct() { ONFActivate::register_admin_scripts(); ONFActivate::register_wp_scripts(); } // 静态激活方法,专供激活钩子调用 public static function activate() { ONFActivate::activate(); } // 静态停用方法,专供停用钩子调用 public static function deactivate() { ONFDeactivate::deactivate(); ONFDeactivate::dequeue_admin(); // 直接调用卸载逻辑,无需挂钩子 ONFDeactivate::unregister_wp_scripts(); } public static function encrypt_conn() { return new ONFRSAEncrypt(); } public function decrypt_data() { return new ONFRSADecrypt(); } }
2. 修正入口文件的钩子绑定
修改onfeed.php,直接绑定类的静态方法作为钩子回调,同时延迟实例化类到插件正常加载阶段:
// 确保插件路径常量已定义(如果没有的话添加) if (!defined('ONFEED_PLUGIN_PATH')) { define('ONFEED_PLUGIN_PATH', plugin_dir_path(__FILE__)); } require_once ONFEED_PLUGIN_PATH . '/vendor/autoload.php'; use Oppimittinetworking\OnfeedFacebook\OnFeedMain; // 激活钩子:绑定静态方法 register_activation_hook( __FILE__, array( OnFeedMain::class, 'activate' ) ); // 停用钩子:绑定静态方法 register_deactivation_hook( __FILE__, array( OnFeedMain::class, 'deactivate' ) ); // 插件正常加载时再实例化类 add_action('plugins_loaded', function() { if (class_exists(OnFeedMain::class)) { new OnFeedMain(); } });
3. 修复停用类的脚本卸载逻辑
修改ONFDeactivate.php,移除无效的钩子绑定,直接在停用方法中执行卸载逻辑(因为插件停用后不会再触发admin_dequeue_scripts钩子):
namespace Oppimittinetworking\OnfeedFacebook\Action; class ONFDeactivate { public static function deactivate() { // 直接执行脚本卸载逻辑 self::dequeue_admin(); // 原有的停用业务逻辑... } public static function unregister_wp_scripts() { // TODO 直接执行前端脚本卸载逻辑,不要挂钩子 } public static function dequeue_admin() { // 先注销再卸载,确保彻底清除 wp_deregister_style( "onfeed_main_css" ); wp_deregister_style( "onfeed_shortcut_css" ); wp_deregister_style( "onfeed_feedspage_css" ); wp_deregister_script( "onfeed_main_js" ); wp_deregister_script( "onfeed_shortcut_js" ); wp_deregister_script( "onfeed_feedspage_js" ); wp_dequeue_style( "onfeed_main_css" ); wp_dequeue_style( "onfeed_shortcut_css" ); wp_dequeue_style( "onfeed_feedspage_css" ); wp_dequeue_script( "onfeed_main_js" ); wp_dequeue_script( "onfeed_shortcut_js" ); wp_dequeue_script( "onfeed_feedspage_js" ); } public static function dequeue_wp() { // TODO } }
4. 刷新Composer自动加载缓存
虽然已执行composer dump-autoload,但开启了optimize-autoloader可能缓存旧的路径映射,重新生成优化版自动加载:
composer dump-autoload -o
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

