Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] Error al cerrar sesion: Warning: Cannot modify header information

Estas en el tema de Error al cerrar sesion: Warning: Cannot modify header information en el foro de PHP en Foros del Web. Hola a todos. Estoy con el tema de las sesiones php y al cerrar la sesión me da el error Cannot modify header information - ...
  #1 (permalink)  
Antiguo 30/05/2013, 05:09
 
Fecha de Ingreso: octubre-2012
Mensajes: 45
Antigüedad: 11 años, 6 meses
Puntos: 2
Error al cerrar sesion: Warning: Cannot modify header information

Hola a todos. Estoy con el tema de las sesiones php y al cerrar la sesión me da el error Cannot modify header information - headers already sent by (output started at /opt/lampp/htdocs/superguardian/app/vistas/menu.php:105) in /opt/lampp/htdocs/superguardian/app/controladores/login.php on line 18

El caso es que inicia sesión correctamente y de hecho la cierra pero en vez de volver al archivo index me saca ese error.
El index.php
Código:
<?php
session_start();
	//$_SESSION["centro"] = 1;
?>
<html>
	<head>
	   <meta http-equiv="content-type" content="text/html; charset=utf-8">
		<link rel="stylesheet" type="text/css" href="estilos/css/index.css" title="style">
		<!--Hacer limpio el siguiente código más adelante-->
		<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><!--Librería de Jquery-->
		<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script><!--Librería de Jquery UI-->
<!--IMPORTACION DE JS-->
		<script type="text/javascript" src="../librerias/scripts/openwysiwyg/scripts/wysiwyg.js"></script>
		<script type="text/javascript" src="../librerias/scripts/openwysiwyg/scripts/wysiwyg-settings.js"></script>
<!--Carga de todos los js de comprobaciones-->
		<script type="text/javascript" src="../app/js/comprobaciones/formularios.js"></script>
<!--Funciones de jquery tales como la carga de tabs dinámicos-->
		<script type="text/javascript" src="../app/js/funciones_jquery_ui.js"></script> 
<!--Carga el js de ventanas emergentes-->

<!--AL CARGAR LA PÁGINA-->

<script type="text/javascript" >

	$( document ).ready(function() {
//Para que un div se abra con el efecto 		
		$( ".highlight" ).show( "highlight" );
		$( ".blind" ).show( "blind",1000 );	
		
//Multiple checks
		$("#check_todos").click(function(event){
	     if($(this).is(":checked")) {
		 	$(".casilla:checkbox:not(:checked)").attr("checked", "checked");
		 }else{
			 $(".casilla:checkbox:checked").removeAttr("checked");
		 }
	   });
			
});
//Clona la lista de clases de ese centro que hay donde se cambian de clase los alumnos y la añade a la parte de filtros.
//Hace uso de DOM para ello.
$( document ).ready(function() {
	cloneNode=document.getElementById("clases_para_cambiar").cloneNode(true);
	document.getElementById("filtro_aula").appendChild(cloneNode);	
	//Quedaría ver cambiar el name.

});	
</script>



	
<script>
	$(function() {
		$( "#dialog_email" ).dialog({
		autoOpen: false,
		width:800,
		show: {
		effect: "puff",
		duration: 500
		},
		hide: {
		effect: "puff",
		duration: 500
		}
		});
		$( "#email" ).click(function() {
		$( "#dialog_email" ).dialog( "open" );
		});
	});
</script>
		
<!--CÓDIGO PARA QUE LOS BOTONES SE AJUSTEN AL TEMA DE JQUERY UI-->
	<!--	<script>
		  $(function() {
		    $( "input[type=submit], input[type=reset]")
		      .button()
		      .click(function( event ) {
		        event.preventDefault();
		      });
		  });
		 </script>	-->
		<script type="text/javascript">
		//Script para hacer visibles los submenus del menu principal.
			/*$(document).ready(function() {
				$('.menu li:has(ul)').hover(function(e){
					$(this).find('ul').css({display: "block"});
				},
				function(e){
					$(this).find('ul').css({display: "none"});
				});
			});*/
		 </script>

	</head>
	<body>
		<?php include('../app/includes_y_requires.php')?>
		
		<!--INICIO DEL CONTENIDO-->
		<div id="contenedor">
			<div id="top">
				<div><span onclick=" document.location.href = 'index.php?c=1'">SUPERGUARDIÁN</span></div>
				<div>
				<input type="text" class="search" size="50" />
				<button type="button" onclick="session_destroy()">Buscar</button>
				</div>
				<div><?php
					include("../app/vistas/menu.php");
				?>
				</div>
			</div>
			<!--Fin de menú-->
			<div id="principal">
				<div id="central">
					<?php
					if(isset($_SESSION["login"])) {
						//$accionPredefinida ="nueva_alta";
							if(!empty($_GET['controlador'])){
									$controlador = $_GET['controlador'];
									if(! empty($_GET['accion']))
										  $accion = $_GET['accion'];
									else{
										 // $accion = $accionPredefinida;

							}
								  
									//Ya tenemos el controlador y la accion.
									//Formamos el nombre del fichero que contiene nuestro controlador
									$controlador = "../app/controladores/".$controlador.".php";
	
									//Incluimos el controlador o detenemos todo si no existe
									if(is_file($controlador))
										  require_once $controlador;
									else
	
										  die('El controlador no existe - 404 not found');
	
									//Llamamos la accion o detenemos todo si no existe
									if(is_callable($accion))
										  $accion();
									else
										 // die('La accion no existe - 404 not found');
										  echo "NO SE HA SOLICITADO UNA ACCIÓN";
							}
						
						  if(empty($_GET['controlador']) && empty($_GET['accion'])){
								//require_once"../app/vistas/nuevo_alumno.php";
								include("../app/vistas/listar_alumnos.php");

						  }
						  }//Fin del if de comprobación de logueado
						  else {
						  		?>
						  			<form method="POST" action="../app/controladores/login.php"">
										<span class="b">ACCESO: </span>
										<span>Usuario</span><input type='text' name="user" value=" " size="10"/>
										<span>Contraseña</span><input type='password' name="pass" value="" size="10"/>
										<input type="submit" value="Entrar"/>
									</form>																	
								<?php	
						  }
					?>				
				</div>
				<!--Fin de central-->			
				<div id="derecha">
				</div>
				<!--Fin de derecha-->
			</div>
			<!--Fin de principal-->
		</div>
		<!--Fin de contenedor-->
	</body>
</html>
Su controlador.php

Código:
<?php
//Si se envía el formulario de login llama a login (modelo) con los parámetros de usuario y contraseña.
	if(isset($_POST['user'])) {		
		require '../modelos/conexion.php';
		require '../modelos/login.php';
		$u=$_POST['user'];
		$p=$_POST['pass'];		

		login($u,$p);
	}

	function cerrar_sesion() {
// Destruir todas las variables de sesión.
		$_SESSION = array();
// Si se desea destruir la sesión completamente, borre también la cookie de sesión.
// Nota: ¡Esto destruirá la sesión, y no la información de la sesión!
		if (ini_get("session.use_cookies")) {
	   	$params = session_get_cookie_params();
	    	setcookie(session_name(), '', time() - 42000,
	      $params["path"], $params["domain"],
	      $params["secure"], $params["httponly"]
	    	);
		}
// Finalmente, destruir la sesión.
		session_destroy();
		header("Location: ../../publico/index.php?");
	}
?>
Y su modelo.php

Código:
<?php
function login($u,$p){
			session_start();
	global $servidor, $bd, $usuario, $contrasenia;
	try{
		@ $db = new mysqli($servidor, $usuario, $contrasenia);
		if (mysqli_connect_errno() != 0)
			throw new Exception('Error conectando:'.mysqli_connect_error(), mysqli_connect_errno());
		
		$db->select_db($bd);
		if ($db->errno != 0)
			throw new Exception('Error seleccionando bd:'.$db->error, $db->errno);
		$consulta = $db->query("SELECT * FROM usuarios WHERE email='".$u."' AND password='".$p."'");
		
		if (mysqli_num_rows ($consulta) > 0){
			$_SESSION['login']=1;
			header("Location: ../../publico/index.php");
		}
		else {
			echo "Usuario o contraseña no coinciden";
			
		}

		if ($db->errno != 0)
			throw new Exception('Error realizando consulta:'.$db->error, $db->errno); 
		$db->close(); 
	}catch (Exception $e){
		echo $e->getMessage();
		if (mysqli_connect_errno() == 0)
			$db->close();
		exit();
	}	
	return $consulta;	
}

?>

Y el del menu.php
Código:
<ul class="menu"><img src="../pruebas/cara.jpg" alt="Configuración"/>
	<li><a>Perfil</a></li>
	<li><a href="#">tyutyuy</a></li>
	<li><a href="index.php?controlador=login&accion=cerrar_sesion">Salir</a></li>
</ul>
He visto soluciones del tipo comentar x linea en php.ini y cosas como que puede ser algún espacio. No quiero hacer trampas al servidor y no creo que tenga ningún espacio o carácter raro.

¿De que podría venir el fallo?

Última edición por yafuslae; 30/05/2013 a las 05:11 Razón: olvidé el menu.php
  #2 (permalink)  
Antiguo 30/05/2013, 05:27
 
Fecha de Ingreso: febrero-2013
Mensajes: 163
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

No se si no estoy ubicando ese header en tu código o es que no pusiste el código completo. Con mi escaso conocimiento de PHP puedo decirte que el header no funciona y muestra ese error si hay alguna linea HTML o algún echo antes del header .. no se si sea eso
  #3 (permalink)  
Antiguo 30/05/2013, 05:47
 
Fecha de Ingreso: octubre-2012
Mensajes: 45
Antigüedad: 11 años, 6 meses
Puntos: 2
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Así por lo pronto yo ya se que el fallo está en el controlador en las partes en negrita ya que si quito esa parte del código, aun que no cargue la página que ha de cargar, al menos no da el error. No obstante no es la solución, por que necesito que al salir de la sesión haga el else principal del index.php y para eso he de usar el header("Location: ../../publico/index.php del controlador.

Código:
else {
						  		?>
						  			<form method="POST" action="../app/controladores/login.php"">
										<span class="b">ACCESO: </span>
										<span>Usuario</span><input type='text' name="user" value="" size="10"/>
										<span>Contraseña</span><input type='password' name="pass" value="" size="10"/>
										<input type="submit" value="Entrar"/>
									</form>																	
								<?php	
						  }
Código:
// Si se desea destruir la sesión completamente, borre también la cookie de sesión.
// Nota: ¡Esto destruirá la sesión, y no la información de la sesión!
		if (ini_get("session.use_cookies")) {
	   	$params = session_get_cookie_params();
	    	setcookie(session_name(), '', time() - 42000,
	      $params["path"], $params["domain"],
	      $params["secure"], $params["httponly"]
	    	);
		}
// Finalmente, destruir la sesión.
		session_destroy();
		header("Location: ../../publico/index.php");
 
  #4 (permalink)  
Antiguo 30/05/2013, 06:17
Avatar de rodrigo791  
Fecha de Ingreso: noviembre-2009
Ubicación: Uruguay
Mensajes: 1.339
Antigüedad: 14 años, 5 meses
Puntos: 168
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Lea esto: http://www.php.net/manual/es/function.header.php

Recuerde que header() debe ser llamado antes de mostrar nada por pantalla, etiquetas HTML, líneas en blanco desde un fichero o desde PHP. Es un error muy común leer código con funciones como include o require, u otro tipo de funciones de acceso de ficheros que incluyen espacios o líneas en blanco que se muestran antes de llamar a la función header(). Sucede el mismo problema cuando se utiliza un solo fichero PHP/HTML.
  #5 (permalink)  
Antiguo 30/05/2013, 07:01
 
Fecha de Ingreso: octubre-2012
Mensajes: 45
Antigüedad: 11 años, 6 meses
Puntos: 2
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Realmente lo que hace ese header es llamar al index. En index se encuentra un condicional que hace que si la $_SESSION['login'] existe cargará un código que mostrará una serie de cosas en pantalla, de lo contrario muestra el formulario de login. No veo por ahí nada raro, y por eso no se como solucionarlo.
  #6 (permalink)  
Antiguo 30/05/2013, 07:07
 
Fecha de Ingreso: mayo-2013
Mensajes: 169
Antigüedad: 10 años, 10 meses
Puntos: 25
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Cita:
Iniciado por yafuslae Ver Mensaje
Realmente lo que hace ese header es llamar al index. En index se encuentra un condicional que hace que si la $_SESSION['login'] existe cargará un código que mostrará una serie de cosas en pantalla, de lo contrario muestra el formulario de login. No veo por ahí nada raro, y por eso no se como solucionarlo.
Comprueba que no tengas un espacio en la primera linea del codigo antes de abrir la etiqueta de php
Código PHP:
<?php

?>
No debe haber espacio, ni tabulaciones, ni salto de linea en la primera linea del script. Es decir antes de la primera etiqueta <?php

Suele ser el error más común cuando se trabaja con redireccionamientos con header. A lo mejor sin darte cuenta, dejas un espacio en blanco arriba del documento, o un salto de linea. Y eso lo interpreta PHP como salida a mostrar.
  #7 (permalink)  
Antiguo 30/05/2013, 07:12
Avatar de rodrigo791  
Fecha de Ingreso: noviembre-2009
Ubicación: Uruguay
Mensajes: 1.339
Antigüedad: 14 años, 5 meses
Puntos: 168
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Tendrás que ir depurando parte por parte de tu código para saber si estás teniendo mensajes en pantalla luego del header, de error por ejemplo, de los que te devuelven las funciones.
  #8 (permalink)  
Antiguo 30/05/2013, 07:22
 
Fecha de Ingreso: octubre-2012
Mensajes: 45
Antigüedad: 11 años, 6 meses
Puntos: 2
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Amiancht, he comprobado eso y no parece que exista nada raro.
rodrigo791, el problema lo da el if y el header en el controlador.
Código:
// Si se desea destruir la sesión completamente, borre también la cookie de sesión.
// Nota: ¡Esto destruirá la sesión, y no la información de la sesión!
		if (ini_get("session.use_cookies")) {
	   	$params = session_get_cookie_params();
	    	setcookie(session_name(), '', time() - 42000,
	      $params["path"], $params["domain"],
	      $params["secure"], $params["httponly"]
	    	);
		}
// Finalmente, destruir la sesión.
		session_destroy();
		header("Location: ../../publico/index.php");
De todos modos intenté ver en firebug si existía algún otro error y no dice nada. Lo que tiene que decir ya lo dice por pantalla.
  #9 (permalink)  
Antiguo 30/05/2013, 07:45
 
Fecha de Ingreso: mayo-2013
Mensajes: 169
Antigüedad: 10 años, 10 meses
Puntos: 25
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

ya he visto el problema y es lo que deciamos.
el controlador lo estas llamando aquí en el index.php
Código PHP:
//Ya tenemos el controlador y la accion.
                                    //Formamos el nombre del fichero que contiene nuestro controlador
                                    
$controlador "../app/controladores/".$controlador.".php";
    
                                    
//Incluimos el controlador o detenemos todo si no existe
                                    
if(is_file($controlador))
                                          require_once 
$controlador;
                                    else 
Y en el controlador es donde estas haciendo el header... en el archivo controlador.php
Pero claro antes de llamar a ese archivo con require_once ya has generado codigo HTML que se muestra al navegador. Por lo que el Header te da error. No se puede mostrar o generar ninguna salida antes de usar el comando header.
  #10 (permalink)  
Antiguo 30/05/2013, 08:56
 
Fecha de Ingreso: octubre-2012
Mensajes: 45
Antigüedad: 11 años, 6 meses
Puntos: 2
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

No estoy seguro de que el problema sea ese. Ese controlador solo se ejecutaría en caso de que la sesión login existiese. Cuando no existe se ejecuta un formulario que al enviar va al controlador login especifico que es el que puse el código en la explicación del problema.
Código:
  else {
						 ?>
						 	<form method="POST" action="../app/controladores/login.php"">
							<span class="b">ACCESO: </span>
							<span>Usuario</span><input type='text' name="user" value="" size="10"/>
							<span>Contraseña</span><input type='password' name="pass" value="" size="10"/>
							<input type="submit" value="Entrar"/>	
	</form>																	
					<?php
  #11 (permalink)  
Antiguo 30/05/2013, 09:22
 
Fecha de Ingreso: mayo-2013
Mensajes: 169
Antigüedad: 10 años, 10 meses
Puntos: 25
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Cannot modify header information - headers already sent by (output started at /opt/lampp/htdocs/superguardian/app/vistas/menu.php:105) in /opt/lampp/htdocs/superguardian/app/controladores/login.php on line 18

El error dice claramente que la informacion de header no se pudo modificar porque, ya fue enviado por los siguientes scripts: Menu.php en linea 105 y login.php en linea 18.

Es decir, se ha enviado ya contenido html, o texto antes de usar la función header.

Si lo que estas ejecutando es el index.php y en el es el que hace un require o include de los scripts mencionados. Entonces yo veo que ya hay codigo html en el script index.php antes de llamar a esos scripts. No puedes mostrar codigo html, antes de hacer un header.

Los redireccionamientos de codigo, usando la función header, deben ir antes de cualqueir codigo html o salida.
  #12 (permalink)  
Antiguo 30/05/2013, 09:46
Avatar de alexisverano  
Fecha de Ingreso: septiembre-2008
Ubicación: La Habana.Cuba
Mensajes: 298
Antigüedad: 15 años, 7 meses
Puntos: 36
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Bueno, un tanto que no entiendo muy bien, que quieres hacer con el header, pero como te han dicho todos los demas, debes implementarlo siempre antes que cualquier otro codigo, aqui un ejemplo muy basico...

Código PHP:
Ver original
  1. include("../../includes/conexion.php");
  2. include("../../includes/session.php");
  3. if (isset($_SESSION['id']) == '')
  4. header("Location: ../../index.php");

Sencillo antes de accder a cualquier pagina o su propio codigo, chequeas que cualquier variable venga llena, de lo contrario redireccionas a donde estimes conveniente.

Saludos,
  #13 (permalink)  
Antiguo 30/05/2013, 09:54
 
Fecha de Ingreso: octubre-2012
Mensajes: 45
Antigüedad: 11 años, 6 meses
Puntos: 2
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Creo que no tengo muy claro el concepto. De todas maneras por poner un ejemplo, hay una parte donde hago esto:

Código PHP:
//Para cuando quiera ver los datos de un alumno
    
if(isset($_POST['ver'])) {        
        
$a=$_POST['ver'];
        
header("Location: ../../publico/index.php?controlador=alumnos&accion=ver_datos_alumno&id=$a");    
    } 
que lo que hace es recoge un dato de un formulario y después haciendo uso de mvc llama a un controlador y a una función de este. Pero para eso carga primero el index, que es quien se encarga de redireccionar. ¿Quieres decir que si cargo con header solamente el index.php es cuando da el problema? Lo digo por que en el ejemplo anterior no me lo da.

Disculpa si no lo acabo de entender pero todavía me queda mucho por aprender.

EDITO:

alexisverano mi idea es evitar ese fallo y que después cargue el index.php. Este archivo contiene un condicional en el cual si no existe $_SESSION['login'] se va al else y muestra un formulario de login. En estos momentos cerrar sesión la cierra, lo se por que si recargo la página a mano se va al formulario de login. El problema es el error que da.

Última edición por yafuslae; 30/05/2013 a las 10:01 Razón: Ampliar
  #14 (permalink)  
Antiguo 30/05/2013, 10:17
Avatar de Nemutagk
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: México
Mensajes: 2.633
Antigüedad: 20 años
Puntos: 406
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Tu problema es que estas implementando MAL el MVC, que caso tiene implementar MVC si el index.php esta repleto de cosas que contradicen el MVC, la idea de dicho paradigma es que se separe toda la lógica de la vista y tu lo que haces es primero cargar la vista (tu layout principal) y luego realizar toda la lógica de controlador/modelo cuando es al revés, primero realizas la lógica del controlador/modelo y LUEGO cargas el layout principal y le agregas la vista pertinente al layout principal, tu error es por todo eso, PHP primero envía todo el código HTML que tienes antes de llamar y ejecutar tu controlador, por lo tanto las cabeceras ya fueron enviadas, y al llamar header() se lanzará el error de que las cabeceras ya fueron enviadas...

Si vas a implentar un paradigma primero comprende bien como funciona y como debe de ser implementado, ya que lo que tienes NO es MVC....
__________________
Listo?, tendría que tener 60 puntos menos de IQ para considerarme listo!!!
-- Sheldon Cooper
http://twitter.com/nemutagk
PD: No contestaré temas vía mensaje personal =)
  #15 (permalink)  
Antiguo 30/05/2013, 10:42
 
Fecha de Ingreso: octubre-2012
Mensajes: 45
Antigüedad: 11 años, 6 meses
Puntos: 2
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Nemutagk, bueno, no se, es el modo en que a mi me han enseñado el mvc. Por otro lado he probado, solo por comprobar si el fallo es al hacer header hacia index.php y parece que no, por que he sustituido el header("Location: ../../publico/index.php?"); por header("Location: http://www.google.es"); y el error sigue siendo
Warning: Cannot modify header information - headers already sent by (output started at /opt/lampp/htdocs/superguardian/app/vistas/menu.php:102) in /opt/lampp/htdocs/superguardian/app/controladores/login.php on line 22

Warning: Cannot modify header information - headers already sent by (output started at /opt/lampp/htdocs/superguardian/app/vistas/menu.php:102) in /opt/lampp/htdocs/superguardian/app/controladores/login.php on line 26
  #16 (permalink)  
Antiguo 30/05/2013, 11:38
 
Fecha de Ingreso: octubre-2012
Mensajes: 45
Antigüedad: 11 años, 6 meses
Puntos: 2
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Haré un doble post pero solo para zanjar el problema. Por algún motivo enviaba el header más de una vez. He solucionado el problema llamando a un archivo llamado logout.php con el siguiente código a través de un enlace (a href).

Código PHP:
<?php 
session_start
();
    if (isset (
$_SESSION['login'])){
        
$_SESSION = array();
// Si se desea destruir la sesión completamente, borre también la cookie de sesión.
// Nota: ¡Esto destruirá la sesión, y no la información de la sesión!
        
if (ini_get("session.use_cookies")) {
           
$params session_get_cookie_params();
            
setcookie(session_name(), ''time() - 42000,
          
$params["path"], $params["domain"],
          
$params["secure"], $params["httponly"]
            );
        }
//Destruye la sesión del todo.    
        
session_destroy();
    }
    
header("Location: ../../publico/index.php");
?>
  #17 (permalink)  
Antiguo 30/05/2013, 11:48
 
Fecha de Ingreso: mayo-2013
Mensajes: 169
Antigüedad: 10 años, 10 meses
Puntos: 25
Respuesta: Error al cerrar sesion: Warning: Cannot modify header information

Si, esa es la forma, que podías hacerlo sin tener que reestructurar todo el codigo de nuevo. Con un enlace a otro archivo. Y ya en ese otro script cerrar sesión y redirigir a la pagina.

Me alegro que lo solucionaras.

Etiquetas: cerrar, sesión
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:25.