大家好,今天咱们来扒一扒 WordPress 后台的“守门神”—— is_admin()
函数。别看它名字简单,背后的逻辑可有点意思。它就像一个尽职尽责的保安,负责判断当前的请求是不是要进入 WordPress 的后台“禁地”。
开场白:后台的“结界”
想象一下,WordPress 后台就像一个神秘的魔法学院,只有拥有通行证的人才能进入学习魔法。这个通行证就是 is_admin()
函数返回的 true
。如果它返回 false
,那对不起,你只能在学院外面溜达溜达。
那么,这个“保安” is_admin()
究竟是如何辨别请求的呢?关键就在于它仔细检查了 $_SERVER['REQUEST_URI']
这个“线索”。
一、$_SERVER['REQUEST_URI']
是什么?
$_SERVER
是一个 PHP 超全局变量,它包含了服务器和执行环境的信息。$_SERVER['REQUEST_URI']
里面存储的是用户在浏览器地址栏中输入的请求 URI,也就是从域名之后到问号(如果有的话)之前的部分。
举个例子:
- 如果用户访问
https://example.com/wp-admin/index.php
,那么$_SERVER['REQUEST_URI']
的值就是/wp-admin/index.php
。 - 如果用户访问
https://example.com/wp-admin/post.php?post=123
,那么$_SERVER['REQUEST_URI']
的值就是/wp-admin/post.php?post=123
。 - 如果用户访问
https://example.com/some-page
,那么$_SERVER['REQUEST_URI']
的值就是/some-page
。
简单来说,$_SERVER['REQUEST_URI']
就是用户在浏览器地址栏中输入的内容中,域名之后的部分。
二、is_admin()
的源码剖析
现在,让我们深入到 is_admin()
的源码中,看看它是如何利用 $_SERVER['REQUEST_URI']
来判断是否为后台请求的。
function is_admin() {
if ( isset( $GLOBALS['is_admin'] ) ) {
return $GLOBALS['is_admin'];
}
if ( defined( 'WP_ADMIN' ) ) {
$GLOBALS['is_admin'] = WP_ADMIN;
return $GLOBALS['is_admin'];
}
$current_file = basename( $_SERVER['SCRIPT_FILENAME'] );
// Check if install.php is being run.
if ( 'install.php' === $current_file ) {
$GLOBALS['is_admin'] = false;
return $GLOBALS['is_admin'];
}
$admin_base_path = rtrim( str_replace( basename( ABSPATH ), '', str_replace( '\', '/', ABSPATH ) ), '/' );
$is_admin = false;
if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
$admin_url_slug = untrailingslashit( str_replace( $admin_base_path, '', admin_url() ) );
$is_admin = false !== strpos( $_SERVER['REQUEST_URI'], $admin_url_slug );
}
/**
* Filters whether the current request is for an administrative interface page.
*
* @since 2.0.0
*
* @param bool $is_admin Whether the request is for an administrative interface page.
*/
$GLOBALS['is_admin'] = (bool) apply_filters( 'admin_init', $is_admin );
return $GLOBALS['is_admin'];
}
让我们一步一步地解读这段代码:
-
检查全局变量
$GLOBALS['is_admin']
和常量WP_ADMIN
:if ( isset( $GLOBALS['is_admin'] ) ) { return $GLOBALS['is_admin']; } if ( defined( 'WP_ADMIN' ) ) { $GLOBALS['is_admin'] = WP_ADMIN; return $GLOBALS['is_admin']; }
这段代码首先检查是否已经设置了全局变量
$GLOBALS['is_admin']
。如果已经设置,就直接返回它的值。这是一种缓存机制,避免重复计算。然后,它检查是否定义了常量
WP_ADMIN
。如果定义了,就把它的值赋给$GLOBALS['is_admin']
并返回。WP_ADMIN
常量通常在wp-config.php
文件中定义,用于强制指定是否为后台请求。 -
检查是否是
install.php
:$current_file = basename( $_SERVER['SCRIPT_FILENAME'] ); // Check if install.php is being run. if ( 'install.php' === $current_file ) { $GLOBALS['is_admin'] = false; return $GLOBALS['is_admin']; }
这段代码获取当前执行的 PHP 文件的文件名,并检查是否是
install.php
。如果是,就将$GLOBALS['is_admin']
设置为false
并返回。这是因为在安装 WordPress 的过程中,不应该被认为是后台请求。 -
计算后台 URL 的 Slug:
$admin_base_path = rtrim( str_replace( basename( ABSPATH ), '', str_replace( '\', '/', ABSPATH ) ), '/' ); $is_admin = false; if ( ! empty( $_SERVER['REQUEST_URI'] ) ) { $admin_url_slug = untrailingslashit( str_replace( $admin_base_path, '', admin_url() ) ); $is_admin = false !== strpos( $_SERVER['REQUEST_URI'], $admin_url_slug ); }
这段代码是
is_admin()
函数的核心部分。它首先计算后台 URL 的 Slug。$admin_base_path
获取 WordPress 安装目录的路径。admin_url()
返回 WordPress 后台的 URL,例如https://example.com/wp-admin/
。str_replace( $admin_base_path, '', admin_url() )
从后台 URL 中移除 WordPress 安装目录的路径,得到类似于/wp-admin/
的字符串。untrailingslashit()
移除字符串末尾的斜杠,得到/wp-admin
。
然后,它使用
strpos()
函数来检查$_SERVER['REQUEST_URI']
中是否包含后台 URL 的 Slug。如果包含,就将$is_admin
设置为true
。 -
应用过滤器
admin_init
:/** * Filters whether the current request is for an administrative interface page. * * @since 2.0.0 * * @param bool $is_admin Whether the request is for an administrative interface page. */ $GLOBALS['is_admin'] = (bool) apply_filters( 'admin_init', $is_admin ); return $GLOBALS['is_admin'];
这段代码使用
apply_filters()
函数来应用admin_init
过滤器。这个过滤器允许开发者自定义是否为后台请求。最后,它将
$is_admin
的值赋给全局变量$GLOBALS['is_admin']
并返回。
三、is_admin()
的判断逻辑总结
用表格总结一下 is_admin()
的判断逻辑:
步骤 | 描述 | 依赖的变量/函数 |
---|---|---|
1 | 检查 $GLOBALS['is_admin'] 是否已设置,如果已设置则直接返回。 |
$GLOBALS['is_admin'] |
2 | 检查 WP_ADMIN 常量是否已定义,如果已定义则将其值赋给 $GLOBALS['is_admin'] 并返回。 |
WP_ADMIN |
3 | 检查当前执行的文件是否为 install.php ,如果是则返回 false 。 |
$_SERVER['SCRIPT_FILENAME'] |
4 | 计算后台 URL 的 Slug。 | ABSPATH , admin_url() |
5 | 检查 $_SERVER['REQUEST_URI'] 中是否包含后台 URL 的 Slug,如果包含则返回 true 。 |
$_SERVER['REQUEST_URI'] |
6 | 应用 admin_init 过滤器,允许开发者自定义判断结果。 |
apply_filters('admin_init', $is_admin) |
四、代码示例:模拟 is_admin()
的行为
为了更好地理解 is_admin()
的工作原理,我们可以编写一个简单的代码示例来模拟它的行为。
<?php
function simulate_is_admin() {
// 模拟 $_SERVER['REQUEST_URI']
$_SERVER['REQUEST_URI'] = '/wp-admin/index.php'; // 或者 '/wp-admin/post.php?post=123' 或者 '/some-page'
// 模拟 ABSPATH 和 admin_url()
define( 'ABSPATH', '/var/www/html/wordpress/' ); // 你的 WordPress 安装目录
function admin_url() {
return 'https://example.com/wp-admin/'; // 你的 WordPress 后台 URL
}
$admin_base_path = rtrim( str_replace( basename( ABSPATH ), '', str_replace( '\', '/', ABSPATH ) ), '/' );
$admin_url_slug = untrailingslashit( str_replace( $admin_base_path, '', admin_url() ) );
$is_admin = false !== strpos( $_SERVER['REQUEST_URI'], $admin_url_slug );
return $is_admin;
}
// 调用模拟函数并输出结果
$is_admin = simulate_is_admin();
if ( $is_admin ) {
echo "这是一个后台请求!";
} else {
echo "这不是一个后台请求。";
}
?>
在这个示例中,我们手动设置了 $_SERVER['REQUEST_URI']
、ABSPATH
和 admin_url()
的值,然后模拟了 is_admin()
函数的核心逻辑。你可以修改 $_SERVER['REQUEST_URI']
的值来测试不同的情况。
五、注意事项和常见问题
$_SERVER['REQUEST_URI']
的可靠性: 理论上,$_SERVER['REQUEST_URI']
的值是由客户端提供的,因此存在被篡改的风险。但是,在实际应用中,这种风险很小。- 使用
is_admin()
的时机:is_admin()
函数应该在admin_init
动作之后调用,以确保 WordPress 已经完成了初始化。 is_admin()
和is_admin_bar_showing()
的区别:is_admin()
用于判断是否为后台请求,而is_admin_bar_showing()
用于判断是否显示管理栏。它们是不同的概念。
六、高级应用:自定义 admin_init
过滤器
通过 admin_init
过滤器,我们可以自定义 is_admin()
函数的返回值。这在某些特殊情况下非常有用。
例如,我们可以根据用户的 IP 地址来判断是否为后台请求:
add_filter( 'admin_init', 'my_custom_is_admin' );
function my_custom_is_admin( $is_admin ) {
$allowed_ips = array( '127.0.0.1', '192.168.1.100' ); // 允许访问后台的 IP 地址
if ( in_array( $_SERVER['REMOTE_ADDR'], $allowed_ips ) ) {
return true;
} else {
return $is_admin; // 保持原来的判断结果
}
}
在这个示例中,我们创建了一个名为 my_custom_is_admin()
的函数,并将其添加到 admin_init
过滤器中。这个函数检查用户的 IP 地址是否在允许的 IP 地址列表中。如果在列表中,就返回 true
,否则返回原来的判断结果。
七、总结:is_admin()
的价值
is_admin()
函数是 WordPress 安全机制的重要组成部分。它通过检查 $_SERVER['REQUEST_URI']
和应用 admin_init
过滤器,有效地判断当前的请求是否要进入后台。了解 is_admin()
的工作原理,可以帮助我们更好地理解 WordPress 的安全机制,并编写更安全的代码。
希望今天的讲座能够帮助大家更好地理解 is_admin()
函数。下次再见!