如何通过MU-Plugin仅禁用已存在的特定插件?
解决MU-Plugin中检测普通插件是否存在的问题
因为MU-Plugin加载优先级高于普通插件,WordPress此时还未完成插件目录的扫描,get_plugins()这类常规函数无法正常返回插件列表,你可以通过手动扫描插件目录+验证插件头的方式获取所有已安装的插件,再结合过滤逻辑实现精准禁用。
具体实现步骤:
- 编写自定义函数扫描
wp-content/plugins目录,识别合法插件(通过检测文件是否包含WordPress插件头注释) - 在你的过滤函数中,先获取所有已安装插件,再从原活动插件列表中移除存在的目标插件
完整代码示例:
<?php add_filter('pre_option_active_plugins', 'filter_active_plugins'); add_filter('pre_site_option_active_sitewide_plugins', 'filter_active_plugins'); function filter_active_plugins($original_value) { // 定义需要禁用的插件(格式:插件主文件路径,比如"akismet/akismet.php") $plugins_to_disable = [ "plugin1/plugin1.php", "plugin2/plugin2.php", "plugin3/plugin3.php" ]; // 获取当前站点所有已安装的合法插件 $installed_plugins = get_all_installed_plugins(); // 筛选出确实存在的要禁用的插件 $existing_plugins_to_disable = array_intersect($plugins_to_disable, array_keys($installed_plugins)); // 处理单站点活动插件列表 if (is_array($original_value)) { return array_diff($original_value, $existing_plugins_to_disable); } // 处理多站点全局活动插件列表(键为插件路径,值为启用时间) elseif (is_array($original_value) && !empty($original_value)) { foreach ($existing_plugins_to_disable as $plugin) { unset($original_value[$plugin]); } return $original_value; } // 若无原数据则返回空数组 return []; } // 自定义函数:扫描并获取所有已安装的合法插件 function get_all_installed_plugins() { $plugins_dir = WP_PLUGIN_DIR; $plugins = []; // 检查插件目录是否存在 if (!is_dir($plugins_dir)) { return $plugins; } $dirs = scandir($plugins_dir); foreach ($dirs as $dir) { // 跳过当前目录、上级目录及隐藏文件 if ($dir === '.' || $dir === '..' || str_starts_with($dir, '.')) { continue; } $dir_path = $plugins_dir . '/' . $dir; // 处理文件夹类型的插件 if (is_dir($dir_path)) { $files = scandir($dir_path); foreach ($files as $file) { if (pathinfo($file, PATHINFO_EXTENSION) === 'php') { $file_path = $dir_path . '/' . $file; // 读取文件前8192字节(足够覆盖插件头注释) $file_content = file_get_contents($file_path, false, null, 0, 8192); // 检测是否包含WordPress插件头的关键标识 if (preg_match('/Plugin Name:/', $file_content)) { $plugin_key = $dir . '/' . $file; $plugins[$plugin_key] = $file; break; // 找到主插件文件后跳出当前文件夹循环 } } } } // 处理根目录下的单文件插件 else if (pathinfo($dir, PATHINFO_EXTENSION) === 'php') { $file_path = $plugins_dir . '/' . $dir; $file_content = file_get_contents($file_path, false, null, 0, 8192); if (preg_match('/Plugin Name:/', $file_content)) { $plugin_key = $dir; $plugins[$plugin_key] = $dir; } } } return $plugins; }
关键说明:
- 插件路径格式:要禁用的插件必须写成
文件夹/主文件.php的格式(比如akismet/akismet.php),和WordPress存储的插件标识一致 - 兼容性:同时支持单站点和多站点环境,处理了
active_plugins(单站点)和active_sitewide_plugins(多站点全局)两种情况 - 性能优化:只读取每个文件的前8192字节,避免加载大文件影响性能
内容的提问来源于stack exchange,提问作者Diego Gallardo
相关产品推荐
相关产品推荐

