Warning: Cannot modify header information - headers already sent......(PHP页面跳转的问题)

本文介绍了当遇到PHP中Header信息无法修改的问题时的几种解决方案,包括移除空白行、使用exit语句、利用JavaScript或输出缓冲等方法,并讨论了各种方法的优缺点。

昨晚在转换许愿板编码的时候,有一个页面需要在head中申明utf-8的编码,但是这与程序中的一处header产生了冲突。google了一下,找到几种解决方法,翻译整理一下:

If you got this message: "Warning: Cannot modify header information - headers already sent by ...."
如果在执行php程序时看到这条警告:"Warning: Cannot modify header information - headers already sent by ...."

Few notes based on the following user posts:
有以下几种解决方法:


1. Blank lines (空白行):
Make sure no blank line after <?php ... ?> of the calling php script.
检查有<?php ... ?> 后面没有空白行,特别是include或者require的文件。不少问题是这些空白行导致的。


2. Use exit statement (用exit来解决):
Use exit after header statement seems to help some people
在header后加上exit();
header ("Location: xxx");
exit();


3. PHP has this annoying problem, if your HTML goes before any PHP code or any header modification before redirecting to certain page, it'll said "Warning: Cannot modify header information - headers already sent by ...." Basically anytime you output to browser, the header is set and cannot be modified.   So two ways to get around the problem:


3a. Use Javascript (用Javascript来解决):
<? echo "<script> self.location(/"file.php/");</script>"; ?>
Since it's a script, it won't modify the header until execution of Javascript.
可以用Javascript来代替header。但是上面的这段代码我没有执行成功... 另外需要注意,采用这种方法需要浏览器支持Javascript.


3b. Use output buffering (用输出缓存来解决):
<?php ob_start(); ?>
... HTML codes ...
<?php
... PHP codes ...
header ("Location: ....");
ob_end_flush();
?>
This will save the output buffer on server and not output to browser yet, which means you can modify the header all you want until the ob_end_flush() statement.   This method is cleaner than the Javascript since Javascript method assumes the browser has Javascript turn on.   However, there are overhead to store output buffer on server before output, but with modern hardware I would imagine it won't be that big of deal.   Javascript solution would be better if you know for sure your user has Javascript turn on on their browser.

就像上面的代码那样,这种方法在生成页面的时候缓存,这样就允许在输出head之后再输出header了。本站的许愿板就是采用这种方法解决的header问题。


4.set output_buffering = On in php.ini (开启php.ini中的output_buffering )
set output_buffering = On will enable output buffering for all files. But this method may slow down your php output. The performance of this method depends on which Web server you're working with, and what kind of scripts you're using.
这种方法和3b的方法理论上是一样的。但是这种方法开启了所有php程序的输出缓存,这样做可能影响php执行效率,这取决于服务器的性能和代码的复杂度。


<?php // 配置数据库连接 $host = 'localhost'; $dbname = 'syxywl.cn_sdk-14'; // 主数据库 $username = 'root'; $password = 'qq28009618'; $dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4"; try { $pdo = new PDO($dsn, $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { die("数据库连接失败: " . htmlspecialchars($e->getMessage())); } // 设置分页参数 $limit = 10; $page = isset($_GET['page']) ? (int)$_GET['page'] : 1; $page = max(1, $page); $offset = ($page - 1) * $limit; // === 获取主键字段名 === function getPrimaryKey($pdo, $table) { $stmt = $pdo->prepare("DESCRIBE `$table`"); $stmt->execute(); $columns = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($columns as $col) { if ($col['Key'] === 'PRI') { return $col['Field']; } } return null; } $primaryKey = getPrimaryKey($pdo, 't_accounts'); if (!$primaryKey) { die("错误:t_accounts 表没有定义主键!"); } // 处理封禁/解封请求 if ($_SERVER['REQUEST_METHOD'] === 'POST') { $pkValue = $_POST[$primaryKey] ?? null; if ($pkValue && in_array($_POST['action'], ['ban', 'unban'])) { try { $type = $_POST['action'] === 'ban' ? 99 : 1; $sql = "UPDATE `t_accounts` SET `type` = ? WHERE `$primaryKey` = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([$type, $pkValue]); $successMsg = "用户 <strong>" . htmlspecialchars($pkValue) . "</strong> 已成功 " . ($_POST['action'] === 'ban' ? '<span style="color:red;">封禁</span>(type=99)' : '<span style="color:green;">解封</span>(type=1)') . "!"; } catch (PDOException $e) { $errorMsg = "操作失败: " . htmlspecialchars($e->getMessage()); } } } // ======== 搜索逻辑开始 ======== $searchResult = null; $searchError = null; if (isset($_GET['search_player_uid']) && trim($_GET['search_player_uid']) !== '') { $rawInput = trim($_GET['search_player_uid']); // 验证是否为纯数字 if (!preg_match('/^\d+$/', $rawInput)) { $searchError = "请输入有效的角色 UID(必须是纯数字)"; } else { $playerUid = (string)$rawInput; try { // 第一步:从 db_hk4e_user_gio.t_player_uid 查 account_uid $sql = "SELECT `account_uid` FROM `db_hk4e_user_gio`.`t_player_uid` WHERE `uid` = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([$playerUid]); $link = $stmt->fetch(PDO::FETCH_ASSOC); if (!$link) { $searchError = "❌ 未找到游戏 UID <strong>$playerUid</strong> 的绑定记录"; } else { $accountUid = $link['account_uid']; // 第二步:在 t_accounts 中查找用户 $sql = "SELECT `uid`, `name`, `type` FROM `t_accounts` WHERE `uid` = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([$accountUid]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if (!$user) { $searchError = "✅ 找到绑定关系,但 SDK 账户 <strong>$accountUid</strong> 在系统中不存在!"; } else { // 第三步:获取该账号所有绑定的角色 $roles = getPlayerRoles($pdo, $user['uid']); $searchResult = [ 'player_uid' => $playerUid, 'account' => $user, 'roles' => $roles ]; } } } catch (PDOException $e) { $searchError = "⚠️ 数据库查询异常: " . htmlspecialchars($e->getMessage()); } } } // ======== 搜索逻辑结束 ======== // === 函数:获取某 account_uid 绑定的所有角色 UID === function getPlayerRoles($pdo, $accountUid) { try { // 检查数据库是否存在 $dbCheck = $pdo->query("SELECT 1 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'db_hk4e_user_gio'"); if ($dbCheck->rowCount() == 0) { return ['error' => '数据库 `db_hk4e_user_gio` 不存在']; } // 检查表是否存在 $tableCheck = $pdo->query(" SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db_hk4e_user_gio' AND TABLE_NAME = 't_player_uid' "); if ($tableCheck->rowCount() == 0) { return ['error' => '表 `t_player_uid` 不存在']; } // 查询绑定的角色 UID $sql = "SELECT `uid` FROM `db_hk4e_user_gio`.`t_player_uid` WHERE `account_uid` = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([(string)$accountUid]); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); return empty($results) ? ['empty' => true] : $results; } catch (PDOException $e) { return ['exception' => $e->getMessage()]; } } // 查询总行数(用于分页) $totalStmt = $pdo->query("SELECT COUNT(*) FROM `t_accounts`"); $totalRows = $totalStmt->fetchColumn(); $totalPages = ceil($totalRows / $limit); // 获取当前页数据 $stmt = $pdo->prepare("SELECT `uid`, `name`, `type` FROM `t_accounts` LIMIT ? OFFSET ?"); $stmt->bindValue(1, $limit, PDO::PARAM_INT); $stmt->bindValue(2, $offset, PDO::PARAM_INT); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); ?> <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>封禁/解封管理系统 + 角色绑定 & 搜索</title> <style> body { font-family: Arial, sans-serif; margin: 20px; background-color: #f7f7f7; color: #333; } h1 { color: #d32f2f; } h2 { color: #1976D2; border-bottom: 1px solid #ddd; padding-bottom: 5px; } table { width: 100%; border-collapse: collapse; margin-top: 20px; background-color: #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.1); } th, td { border: 1px solid #ddd; padding: 10px; text-align: left; } th { background-color: #333; color: white; } .status-banned { background-color: #ffcdd2; color: #c62828; padding: 2px 6px; border-radius: 3px; font-weight: bold; } .status-normal { background-color: #e8f5e8; color: #2e7d32; padding: 2px 6px; border-radius: 3px; } button.ban { background-color: #d32f2f; color: white; border: none; padding: 5px 10px; cursor: pointer; border-radius: 4px; font-weight: bold; margin-right: 5px; } button.unban { background-color: #2e7d32; color: white; border: none; padding: 5px 10px; cursor: pointer; border-radius: 4px; font-weight: bold; } button:hover { opacity: 0.9; } .pagination { margin: 20px 0; text-align: center; } .pagination a, .pagination span { display: inline-block; margin: 0 3px; padding: 8px 12px; text-decoration: none; border: 1px solid #ccc; background-color: #fff; color: #333; border-radius: 4px; } .pagination a:hover { background-color: #333; color: white; } .pagination .current { background-color: #333; color: white; font-weight: bold; } .msg { padding: 10px; margin: 10px 0; border-radius: 4px; } .msg.success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; } .msg.error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; } /* 搜索区域样式 */ .search-box { background: #fff; padding: 15px; border-radius: 8px; box-shadow: 0 1px 6px rgba(0,0,0,0.1); margin-bottom: 20px; } .search-box form { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } .search-box input[type="text"] { padding: 8px; width: 250px; border: 1px solid #ccc; border-radius: 4px; font-size: 1em; } .search-box button { padding: 8px 15px; background: #007BFF; color: white; border: none; border-radius: 4px; cursor: pointer; } .search-box button:hover { background: #0056b3; } </style> </head> <body> <h1>🔐 用户封禁与解封管理系统 + 角色绑定信息</h1> <!-- 搜索框 --> <div class="search-box"> <form method="get"> <label for="search_player_uid"><strong>🔍 通过游戏内UID查找账号:</strong></label> <input type="text" name="search_player_uid" id="search_player_uid" value="<?= htmlspecialchars($_GET['search_player_uid'] ?? '') ?>" placeholder="输入角色 UID(如:2000123)" > <button type="submit">搜索</button> <?php if (isset($_GET['page'])): ?> <input type="hidden" name="page" value="<?= (int)$_GET['page'] ?>"> <?php endif; ?> </form> <!-- 搜索结果提示 --> <?php if ($searchError): ?> <p class="msg error" style="margin-top:10px;"><?= $searchError ?></p> <?php elseif ($searchResult): ?> <p class="msg success" style="margin-top:10px;"> <strong>✅ 找到匹配账号:</strong><br> 游戏角色 UID: <code><?= htmlspecialchars($searchResult['player_uid']) ?></code> ➜ SDK账户排序: <strong><?= htmlspecialchars($searchResult['account']['uid']) ?></strong>, 登陆账户: <strong><?= htmlspecialchars($searchResult['account']['name']) ?></strong> </p> <?php endif; ?> </div> <!-- 操作反馈消息 --> <?php if (isset($successMsg)): ?> <div class="msg success"><?= $successMsg ?></div> <?php endif; ?> <?php if (isset($errorMsg)): ?> <div class="msg error"><?= $errorMsg ?></div> <?php endif; ?> <!-- 搜索结果详情(单独显示) --> <?php if ($searchResult): ?> <h2>📌 搜索结果详情</h2> <table> <thead> <tr> <th>sdk账户排序</th> <th>登陆账户</th> <th>账户状态</th> <th>操作</th> <th>游戏内UID</th> </tr> </thead> <tbody> <tr> <td><?= htmlspecialchars($searchResult['account']['uid']) ?></td> <td><?= htmlspecialchars($searchResult['account']['name']) ?></td> <td> <?php if ($searchResult['account']['type'] == 99): ?> <span class="status-banned">🔴 已封禁</span> <?php else: ?> <span class="status-normal">🟢 正常</span> <?php endif; ?> </td> <td> <form method="post" style="display:inline;"> <input type="hidden" name="<?= htmlspecialchars($primaryKey) ?>" value="<?= htmlspecialchars($searchResult['account']['uid']) ?>"> <?php if ($searchResult['account']['type'] == 99): ?> <input type="hidden" name="action" value="unban"> <button type="submit" class="unban" onclick="return confirm('确定要解封用户 UID=<?= $searchResult['account']['uid'] ?> 吗?')">解封</button> <?php else: ?> <input type="hidden" name="action" value="ban"> <button type="submit" class="ban" onclick="return confirm('确定要封禁用户 UID=<?= $searchResult['account']['uid'] ?> 吗?')">封禁</button> <?php endif; ?> </form> </td> <td> <?php $roles = $searchResult['roles']; ?> <?php if (isset($roles['error'])): ?> <span class="error">❌ <?= htmlspecialchars($roles['error']) ?></span> <?php elseif (isset($roles['exception'])): ?> <span class="error">💥 <?= htmlspecialchars($roles['exception']) ?></span> <?php elseif ($roles['empty']): ?> 此登陆账户未绑定 <?php else: ?> <?php $uids = array_column($roles, 'uid'); echo implode(', ', array_map('htmlspecialchars', $uids)); ?> <?php endif; ?> </td> </tr> </tbody> </table> <br> <?php endif; ?> <!-- 主表格:所有用户列表 --> <?php if (!empty($rows)): ?> <h2>📋 所有 SDK 账户列表</h2> <table> <thead> <tr> <th>sdk账户排序</th> <th>登陆账户</th> <th>账户状态</th> <th>操作</th> <th>游戏内UID</th> </tr> </thead> <tbody> <?php foreach ($rows as $row): ?> <tr> <td><?= htmlspecialchars($row['uid']) ?></td> <td><?= htmlspecialchars($row['name']) ?></td> <td> <?php if ($row['type'] == 99): ?> <span class="status-banned">🔴 已封禁</span> <?php else: ?> <span class="status-normal">🟢 正常</span> <?php endif; ?> </td> <td> <form method="post" style="display:inline;"> <input type="hidden" name="<?= htmlspecialchars($primaryKey) ?>" value="<?= htmlspecialchars($row['uid']) ?>"> <?php if ($row['type'] == 99): ?> <input type="hidden" name="action" value="unban"> <button type="submit" class="unban" onclick="return confirm('确定要解封用户 UID=<?= $row['uid'] ?> 吗?')">解封</button> <?php else: ?> <input type="hidden" name="action" value="ban"> <button type="submit" class="ban" onclick="return confirm('确定要封禁用户 UID=<?= $row['uid'] ?> 吗?')">封禁</button> <?php endif; ?> </form> </td> <td> <?php $roles = getPlayerRoles($pdo, $row['uid']); ?> <?php if (isset($roles['error'])): ?> <span class="error">❌ <?= htmlspecialchars($roles['error']) ?></span> <?php elseif (isset($roles['exception'])): ?> <span class="error">💥 <?= htmlspecialchars($roles['exception']) ?></span> <?php elseif ($roles['empty']): ?> 此登陆账户未绑定 <?php else: ?> <?php $uids = array_column($roles, 'uid'); echo implode(', ', array_map('htmlspecialchars', $uids)); ?> <?php endif; ?> </td> </tr> <?php endforeach; ?> </tbody> </table> <!-- 分页 --> <div class="pagination"> <?php if ($page > 1): ?> <a href="?<?= http_build_query(array_merge($_GET, ['page' => $page - 1])) ?>">上一页</a> <?php else: ?> <span>上一页</span> <?php endif; ?> <?php $start = max(1, $page - 1); $end = min($totalPages, $start + 2); if ($start > 1): ?> <a href="?<?= http_build_query(array_merge($_GET, ['page' => 1])) ?>">1</a> <?php if ($start > 2): ?><span>...</span><?php endif; ?> <?php endif; ?> <?php for ($i = $start; $i <= $end; $i++): ?> <?php if ($i == $page): ?> <span class="current"><?= $i ?></span> <?php else: ?> <a href="?<?= http_build_query(array_merge($_GET, ['page' => $i])) ?>"><?= $i ?></a> <?php endif; ?> <?php endfor; ?> <?php if ($end < $totalPages): ?> <?php if ($end < $totalPages - 1): ?><span>...</span><?php endif; ?> <a href="?<?= http_build_query(array_merge($_GET, ['page' => $totalPages])) ?>"><?= $totalPages ?></a> <?php endif; ?> <?php if ($page < $totalPages): ?> <a href="?<?= http_build_query(array_merge($_GET, ['page' => $page + 1])) ?>">下一页</a> <?php else: ?> <span>下一页</span> <?php endif; ?> <span style="margin-left: 20px;">共 <?= number_format($totalRows) ?> 条记录,<?= $totalPages ?> 页</span> </div> <?php else: ?> <p>该表中没有数据。</p> <?php endif; ?> </body> </html> 点击封禁或解封后重新跳转至指定链接 http://150.138.84.7:333 完整写出
最新发布
10-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值