WordPress后台非管理员禁止访问指定菜单页面的代码修正
解决WordPress非管理员后台菜单隐藏与访问限制问题
问题说明
需要实现:仅允许站点管理员(用户ID=1)访问指定后台菜单项,对其他用户隐藏菜单并禁止直接访问对应页面。需限制的页面URL如下:
https://www.mysite1.com/wp-admin/edit.phphttps://www.mysite1.com/wp-admin/tools.phphttps://www.mysite1.com/wp-admin/options-general.phphttps://www.mysite1.com/wp-admin/admin.php?page=wpcf7https://www.mysite1.com/wp-admin/edit.php?post_type=acf-field-grouphttps://www.mysite1.com/wp-admin/admin.php?page=menu-image-optionshttps://www.mysite1.com/wp-admin/admin.php?page=revslider
已成功实现菜单隐藏功能,代码如下:
add_action( 'admin_init', 'hide_admin_menu_items' ); function hide_admin_menu_items() { $current_user_id = get_current_user_id(); if ($current_user_id != 1) { remove_menu_page('edit.php'); // 文章 remove_menu_page('wpcf7'); // Contact Form 7 remove_menu_page('tools.php'); // 工具 remove_menu_page('options-general.php'); // 设置 remove_menu_page('edit.php?post_type=acf-field-group'); // ACF字段组 remove_menu_page('menu-image-options'); // 菜单图片插件 remove_menu_page('revslider'); // 滑块插件 } }
但访问限制部分针对插件页面(Contact Form7、菜单图片、Revslider)的代码无效,原代码如下:
// 限制后台页面访问(部分插件页面无效) add_action( 'load-edit.php', 'prevent_admin_access' ); // 文章 add_action( 'load-wpcf7', 'prevent_admin_access' ); // Contact Form7 - 无效 add_action( 'load-tools.php', 'prevent_admin_access' ); // 工具 add_action( 'load-options-general.php', 'prevent_admin_access' ); // 设置 add_action( 'load-acf-field-group', 'prevent_admin_access' ); // ACF插件 add_action( 'load-menu-image-options', 'prevent_admin_access' ); // 菜单图片插件 - 无效 add_action( 'load-revslider', 'prevent_admin_access' ); // 滑块插件 - 无效 function prevent_admin_access() { // 原代码存在$user_ID未定义的问题 var_dump($user_ID); exit; if ( $user_ID != 1 ) { wp_die("You are not permitted to access this page!"); exit(); } }
核心问题分析
对于admin.php?page=xxx这类插件页面,WordPress实际加载的核心文件是admin.php,而非xxx.php,因此直接使用load-xxx钩子不会触发。此外原代码中$user_ID未定义,导致用户判断逻辑失效。
正确实现代码
以下是统一处理菜单隐藏与访问限制的完整代码,解决了插件页面限制无效的问题:
// 1. 隐藏非管理员的后台菜单 add_action( 'admin_init', 'hide_admin_menu_items' ); function hide_admin_menu_items() { $current_user_id = get_current_user_id(); if ($current_user_id != 1) { remove_menu_page('edit.php'); remove_menu_page('wpcf7'); remove_menu_page('tools.php'); remove_menu_page('options-general.php'); remove_menu_page('edit.php?post_type=acf-field-group'); remove_menu_page('menu-image-options'); remove_menu_page('revslider'); } } // 2. 禁止非管理员直接访问限制页面 add_action( 'admin_init', 'restrict_admin_page_access' ); function restrict_admin_page_access() { $current_user_id = get_current_user_id(); // 仅对非管理员用户进行限制 if ($current_user_id == 1) return; // 获取当前页面的核心文件与参数 $current_page = basename($_SERVER['PHP_SELF']); $restricted_pages = [ // 直接PHP页面 'edit.php', 'tools.php', 'options-general.php', ]; $restricted_admin_pages = [ // admin.php?page=xxx 类型的页面 'wpcf7', 'menu-image-options', 'revslider', ]; $restricted_post_types = [ // edit.php?post_type=xxx 类型的页面 'acf-field-group', ]; // 检查直接PHP页面 if (in_array($current_page, $restricted_pages)) { wp_die('你无权访问此页面!'); } // 检查admin.php带page参数的页面 if ($current_page === 'admin.php' && isset($_GET['page']) && in_array($_GET['page'], $restricted_admin_pages)) { wp_die('你无权访问此页面!'); } // 检查带post_type参数的页面 if ($current_page === 'edit.php' && isset($_GET['post_type']) && in_array($_GET['post_type'], $restricted_post_types)) { wp_die('你无权访问此页面!'); } }
关键说明
- 用户判断优化:使用
get_current_user_id()直接获取当前用户ID,避免未定义变量的问题。 - 页面判断逻辑:
- 针对直接PHP页面:通过
basename($_SERVER['PHP_SELF'])获取当前加载的文件名称进行匹配 - 针对
admin.php?page=xxx页面:先判断核心文件是admin.php,再检查$_GET['page']参数值 - 针对
edit.php?post_type=xxx页面:判断核心文件是edit.php,再检查$_GET['post_type']参数值
- 针对直接PHP页面:通过
- 统一钩子处理:使用
admin_init钩子统一处理所有访问限制,无需单独添加多个load-钩子,逻辑更清晰且高效。
内容的提问来源于stack exchange,提问作者daro2013
相关产品推荐
相关产品推荐

