You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress后台非管理员禁止访问指定菜单页面的代码修正

解决WordPress非管理员后台菜单隐藏与访问限制问题

问题说明

需要实现:仅允许站点管理员(用户ID=1)访问指定后台菜单项,对其他用户隐藏菜单并禁止直接访问对应页面。需限制的页面URL如下:

  • https://www.mysite1.com/wp-admin/edit.php
  • https://www.mysite1.com/wp-admin/tools.php
  • https://www.mysite1.com/wp-admin/options-general.php
  • https://www.mysite1.com/wp-admin/admin.php?page=wpcf7
  • https://www.mysite1.com/wp-admin/edit.php?post_type=acf-field-group
  • https://www.mysite1.com/wp-admin/admin.php?page=menu-image-options
  • https://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('你无权访问此页面!');
  }
}

关键说明

  1. 用户判断优化:使用get_current_user_id()直接获取当前用户ID,避免未定义变量的问题。
  2. 页面判断逻辑:
    • 针对直接PHP页面:通过basename($_SERVER['PHP_SELF'])获取当前加载的文件名称进行匹配
    • 针对admin.php?page=xxx页面:先判断核心文件是admin.php,再检查$_GET['page']参数值
    • 针对edit.php?post_type=xxx页面:判断核心文件是edit.php,再检查$_GET['post_type']参数值
  3. 统一钩子处理:使用admin_init钩子统一处理所有访问限制,无需单独添加多个load-钩子,逻辑更清晰且高效。

内容的提问来源于stack exchange,提问作者daro2013

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:50:26