
在 WordPress 主题中使用原生 PHP 会话(session)进行登录跳转时,若在 get_header() 等输出函数之后调用 header(),将触发“headers already sent”错误;根本原因在于 HTTP 响应头必须在任何 HTML 输出前发送。
在 wordpress 主题中使用原生 php 会话(session)进行登录跳转时,若在 `get_header()` 等输出函数之后调用 `header()`,将触发“headers already sent”错误;根本原因在于 http 响应头必须在任何 html 输出前发送。
WordPress 模板的执行流程决定了:一旦调用 get_header()、the_content() 或任何直接输出 HTML 的函数,PHP 就已向浏览器发送了响应头和部分响应体,此时再尝试用 header() 修改重定向状态将必然失败。
因此,所有基于会话的身份验证与重定向逻辑,必须置于任何模板输出函数之前。你当前的 page-solutions.php 中先执行 get_header(),再检查会话并重定向,这违反了 HTTP 协议规范。
✅ 正确做法是将权限校验与重定向提前至 get_header() 之前:
<?php /**
* Template Name: Solutions
*/
// ✅ 会话验证必须放在最顶部(且确保 session 已启动)
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
// 注意:WordPress 中推荐使用 wp_redirect() 替代原生 header()
wp_redirect(home_url('/')); // 重定向至首页(front-page.php)
exit; // 必须 exit,防止后续代码执行
}
get_header(); // ✅ 此时才安全加载头部模板
// 后续页面内容...
while (have_posts()) {
the_post();
the_content();
}
get_footer();⚠️ 同时,请注意以下关键细节:
-
session_start() 不应在 header.php 中调用:WordPress 是基于钩子和模板层级的系统,header.php 属于前端渲染阶段,此时输出已开始。正确的会话初始化位置是主题的 functions.php 中,通过 init 钩子安全启动:
// 在 functions.php 中添加 add_action('init', function() { if (session_status() === PHP_SESSION_NONE) { session_start(); } });这确保会话在 WordPress 加载早期(远早于模板输出)就绪,避免重复启动或时机错误。
优先使用 wp_redirect() 而非 header():wp_redirect() 是 WordPress 官方封装函数,自动处理 Location 头、状态码(默认 302),并兼容多环境(如 IIS、Nginx),还支持 wp_safe_redirect() 做 URL 白名单校验,更健壮、更安全。
避免硬编码路径:header("location: home") 是无效写法——它会尝试跳转到相对路径 /home,而非 WordPress 页面。应使用 home_url('/')、wp_login_url() 或 get_permalink(get_option('page_on_front')) 等动态函数生成合规 URL。
总结:WordPress 中的重定向不是纯 PHP 场景,而是与模板生命周期强耦合的操作。牢记「验证先行、输出在后、钩子启动会话、函数封装重定向」四原则,即可彻底规避 headers already sent 错误,并构建可维护的登录保护逻辑。











