PHP数据库操作完成后重定向失效问题求助
问题
执行PHP代码完成数据库操作后,提示语(如"Mis à jour table interventions 1 ok "等)能正常显示,但header()重定向无法跳转到intervention_journaliere.php页面;其他页面的重定向功能正常,修改重定向语句后问题仍未解决。
原代码如下:
<?php // Inclure les fichiers d'initialisation require_once("../inc/init.inc.php"); require_once("../inc/haut.inc.php"); ob_start(); // Assurez-vous que l'intervention_id est passé en paramètre dans l'URL if (isset($_GET['id_intervention']) && is_numeric($_GET['id_intervention'])) { $intervention_id = intval($_GET['id_intervention']); // Récupérez les données existantes de la base de données $selectStmt = $mysqli->prepare("SELECT heure_debut, heure_fin FROM intervention_site WHERE intervention_id = ?"); $selectStmt->bind_param("i", $intervention_id); $selectStmt->execute(); $result = $selectStmt->get_result(); $row = $result->fetch_assoc(); $heure_debut = $row['heure_debut'] ?? null; $heure_fin = $row['heure_fin'] ?? null; $selectStmt->close(); // Extrait les deux premiers caractères pour obtenir l'heure $heure_debut_affichage = substr($heure_debut, 0, 5); // Format "HH:MM" // Vérifiez si le formulaire a été soumis pour l'heure de début if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['heure_debut'])) { // Vérifiez le jeton CSRF if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) { // Jeton CSRF invalide, traitement de l'erreur (par exemple, redirection ou affichage d'un message d'erreur) header("Location: erreur.php"); exit; } // Récupérez l'heure de début depuis $_POST $heure_debut = $_POST['heure_debut']; // Vérifiez si une entrée existe déjà dans la table intervention_site $selectStmt = $mysqli->prepare("SELECT heure_debut FROM intervention_site WHERE intervention_id = ?"); $selectStmt->bind_param("i", $intervention_id); $selectStmt->execute(); $selectStmt->store_result(); if ($selectStmt->num_rows > 0) { // Une entrée existe déjà, effectuez une mise à jour $sql = "UPDATE intervention_site SET heure_debut = ? WHERE intervention_id = ?"; $stmt = $mysqli->prepare($sql); $stmt->bind_param("si", $heure_debut, $intervention_id); if ($stmt->execute()) { // L'heure de début a été mise à jour avec succès // Mettre à jour le statut dans la table interventions à "en cours" $statut = "En cours"; $updateStatusStmt = $mysqli->prepare("UPDATE interventions SET statut = ? WHERE id_intervention = ?"); $updateStatusStmt->bind_param("si", $statut, $intervention_id); if ($updateStatusStmt->execute()) { echo "Mis à jour table interventions 1 ok "; header("Location: intervention_journaliere.php"); exit(); } else { echo "Erreur lors de la mise à jour du statut: " . $updateStatusStmt->error; } echo "Insertion intervention site 2ok "; header("Location: intervention_journaliere.php"); exit(); $updateStatusStmt->close(); } else { echo "Erreur lors de la mise à jour de l'heure de début : " . $stmt->error; } $stmt->close(); } else { // Aucune entrée n'existe, insérez une nouvelle entrée $sql = "INSERT INTO intervention_site (intervention_id, heure_debut) VALUES (?, ?)"; $stmt = $mysqli->prepare($sql); $stmt->bind_param("is", $intervention_id, $heure_debut); if ($stmt->execute()) { // L'heure de début a été insérée avec succès // Mettre à jour le statut dans la table interventions à "en cours" $statut = "En cours"; $updateStatusStmt = $mysqli->prepare("UPDATE interventions SET statut = ? WHERE id_intervention = ?"); $updateStatusStmt->bind_param("si", $statut, $intervention_id); if ($updateStatusStmt->execute()) { echo "Mis à jour table interventions 2 ok "; header("Location: intervention_journaliere.php"); exit(); } else { echo "Erreur lors de la mise à jour du statut: " . $updateStatusStmt->error; } echo "Insertion intervention site 2 ok "; header("Location: intervention_journaliere.php"); exit(); $updateStatusStmt->close(); } else { echo "Erreur lors de l'insertion de l'heure de début : " . $stmt->error; } $stmt->close(); } } // Générez un jeton CSRF et stockez-le en session $csrf_token = bin2hex(random_bytes(32)); $_SESSION['csrf_token'] = $csrf_token; } else { // Ajoutez un message d'erreur ou une redirection ici si nécessaire echo "Erreur : ID d'intervention non valide."; exit; } ?> <div class="container heure-arrivee-container"> <!-- Utilisez une classe spécifique pour le conteneur --> <h2>Validation de l'heure d'arrivée</h2> <form class="intervention-form heure-arrivee-form" method="POST" action="" enctype="multipart/form-data"> <input type="hidden" name="intervention_id" value="<?php echo htmlspecialchars($intervention_id); ?>"> <input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token); ?>"> <label for="heure_debut">Heure d'arrivée :</label> <input type="time" id="heure_debut" name="heure_debut" value="<?php echo htmlspecialchars($heure_debut_affichage); ?>" required> <input type="submit" value="Valider l'heure de début"> </form> <a href="intervention_journaliere.php" class="return-link">Retour aux plannings journaliers</a> </div> <?php ob_end_flush(); // Affiche le contenu mis en mémoire tampon et désactive la mise en mémoire tampon // Inclure le fichier de pied de page require_once("../inc/bas.inc.php"); ?>
问题分析与解决
核心原因
header()前存在输出内容:尽管启用了输出缓冲,但代码中在header()调用前执行了echo输出提示文本,这会触发缓冲内容的发送,导致HTTP头无法正常设置——HTTP协议要求响应头必须在任何实体内容之前发送。- 代码逻辑冗余混乱:在
if ($updateStatusStmt->execute())分支外部,存在多余的echo和header()语句,这些语句会在分支执行完毕后继续运行,不仅逻辑错误,还会再次破坏重定向流程。
修复方案
- 将
ob_start()移至最顶部:确保所有初始化文件的输出都被缓冲,避免意外输出干扰重定向。 - 用Session存储提示信息:不在重定向前直接
echo内容,而是将状态信息存入Session,在目标页面读取显示。 - 修正逻辑分支:移除冗余的
echo和header()语句,确保exit()能终止脚本,避免后续代码执行。
修复后的核心代码片段
<?php ob_start(); // 移至最顶部,覆盖所有输出 require_once("../inc/init.inc.php"); require_once("../inc/haut.inc.php"); // ... 其他代码保持不变 ... if ($stmt->execute()) { $statut = "En cours"; $updateStatusStmt = $mysqli->prepare("UPDATE interventions SET statut = ? WHERE id_intervention = ?"); $updateStatusStmt->bind_param("si", $statut, $intervention_id); if ($updateStatusStmt->execute()) { // 用Session存储成功信息 $_SESSION['success_msg'] = "Mis à jour table interventions 1 ok "; header("Location: intervention_journaliere.php"); exit(); // 终止脚本,避免后续代码执行 } else { $_SESSION['error_msg'] = "Erreur lors de la mise à jour du statut: " . $updateStatusStmt->error; header("Location: intervention_journaliere.php"); exit(); } $updateStatusStmt->close(); } else { $_SESSION['error_msg'] = "Erreur lors de la mise à jour de l'heure de début : " . $stmt->error; header("Location: intervention_journaliere.php"); exit(); } // ... 其他分支按相同逻辑修改 ...
在目标页面显示提示信息
在intervention_journaliere.php的合适位置添加以下代码,用于显示存储的状态信息:
<?php if (isset($_SESSION['success_msg'])) { echo "<div class='success-alert'>" . htmlspecialchars($_SESSION['success_msg']) . "</div>"; unset($_SESSION['success_msg']); // 显示后清除Session } if (isset($_SESSION['error_msg'])) { echo "<div class='error-alert'>" . htmlspecialchars($_SESSION['error_msg']) . "</div>"; unset($_SESSION['error_msg']); } ?>
内容的提问来源于stack exchange,提问作者formboy
相关产品推荐
相关产品推荐

