1. ¡OFERTA! con cupón "DIRVPS": hosting por $0,01 y también VPS Linux y Windows por $0,01 el primer mes por Interserver ← publi
    Descartar aviso
Descartar aviso
Al usar este sitio web, aceptas que nosotros y nuestros socios podamos establecer cookies para fines tales como personalizar el contenido y la publicidad. Más información.

Error PHP: Warning: session_start() Cannot send session cookie - headers already sent

Tema en 'Programación y Diseño Web' iniciado por Apolo, 23 May 2007.

  1. yoseman

    yoseman Usuario activo

    Hola,

    Otra forma de corregir el error de headers already sents, cabeceras ya enviadas, sin tocar el php.ini es anteponer este código al principio

    PHP:
    ob_start();
    y al final

    PHP:
    ob_en_flush();
    Pero estas soluciones no son recomendables en entornos de producción, lo recomendable es tener un flujo que no mande salida al navegador hasta que no se hayan enviado las posibles cabeceras que pueda tener el documento.

    Un saludo ;)
     
    Última edición: 6 Ene 2013
    A Administrador le gusta esto.
  2. yoseman

    yoseman Usuario activo

    ob_end_flush(); Perdón me faltaba una 'd'
     
  3. Sphyr0

    Sphyr0 Usuario activo

    Usar ob_start es una forma de "evitar" el problema, pero no lo corrige.

    Esto es como usar error_reporting(0) o anteponer @ en operaciones que pueden generar errores. No se mostrara, pero el error aun existe :cool:
     
    A FanHost le gusta esto.
  4. yoseman

    yoseman Usuario activo

    No amigo, no es lo mismo.

    error_reporting es una directiva de configuración que lo que hace es eventualmente no mostrarte un error, aunque el error esté ahi, el uso de la @ delante de la función es más de lo mismo pero aplicado sólo a la función.

    Pero ob_start(), aunque puede convertirse en una mala práctica si uno se acostumbra a usarlo simplemente para evitar errores de headers already sents, corrige el error, porque realmente almacena en un buffer de php toda salida hasta que encuentre ob_end_flush() o otra función de enviar el buffer.

    Por eso el error de cabecera ya enviadas ''headers already sents'', por eso puedo decir que ob_start() corrige el error, al contrario que toquetear error_reporting, eso si que directamente es no mostrar los errores.

    Otra cosa es que no sea una buena metodología de trabajo, yo ha habido cosas, en que por ejemplo tengo montado un portal por módulos,y en alguna ocasión queriendo hacer un simple header: location para cambiar de página, me saltaba un error por cabeceras ya enviadas.

    Esta función tambien se usa a veces para modificar el propio bufer que va creando php o realizar sustituciones en el mismo pasándolo a una variable con ob_get_contents(), por eso digo que una cosa es que no haya que acostumbrarse a usarlo sólo para corregir errores de cabeceras ya enviadas, y otra que sea un apaño que no lo es, realmente lo corrige.

    php.net/manual/es/ref.outcontrol.php[/url]

    Un saludo
     
    Última edición: 8 Ene 2013
  5. yoseman

    yoseman Usuario activo

    Mira pongo un ejemplo un poco tonto para que veas en realidad lo que hace que realmente es guardar la salida en un buffer:
    PHP:
    <?php    
    ob_start
    ();
    // Enviamos salida al buffer ya que hemos iniciado con ob_start
    echo "uno mas uno = tres";
    // volcamos en $a el bufer y sustituimos con un str_replace(por ejemplo)
    // ya que se puede tratar como un string
    $a=str_replace("tres","dos",ob_get_contents()) ;
    //Vaciamos el bufer sin mandar la salida y lo desactivamos
    ob_end_clean();
    // enviamos normalmente despues de haber cambiado el contenido del búfer volcando en $a
    echo $a;
    ?>
    Un saludo
     
  6. hostigal

    hostigal Usuario activo

  7. Sphyr0

    Sphyr0 Usuario activo

    error_reporting es una directiva y funcion de PHP; que, mostrara o no los errores generados en el script segun el parametro indicado.

    El que ob_start sirva para ello no significa que debas darle dicho uso, pues como bien mencionas es una mala practica.

    Para mi, usar ob_start para evitar este tipo de situaciones no es mas que un "quick hack", mas no una solucion real :-D

    En este caso especifico, tan simple como no mandar salida antes del header ;) Siempre hay alternativas... :cool:

    Ese es su objetivo :)

    PHP:
    <?php
    ob_start
    ();
    phpinfo();
    $phpinfo ob_get_contents();
    ob_end_clean(); # aunque en este ejemplo ni se requiere
    # edito $phpinfo segun mis necesidades...
    echo $phpinfo;
    ?>
    (El ejemplo que usaste tambien es valido ;))
     
    A Administrador le gusta esto.
  8. yoseman

    yoseman Usuario activo

    Pues si eso mismo dije, pero tu anteriormente dijiste que ob_start es la misma solución que ocultar los errores y que no corrije el problema, y no es así, con ob_start lo solucionas realmente.

    Claro lo que no hay que hacer es coger y decir, me da un error de headers already sents y lo soluciono con las funciones de bufer. Pero eso no significa que no lo corrija.
    Para mi tambien, es lo que dije desde el principio, veo que estamos de acuerdo ;)
    Si eso es obvio.He de hacer hincapié en que al principio dije claramente que ''Pero estas soluciones no son recomendables en entornos de producción'', y tu comentaste seguidamente que ''no corrige el error''. Yo tengo claro el tema de ob_start(), y asi lo dije al principio, si estás desarrollando y quieres solventar el error momentaneamente por la razón que sea, lo puedes usar, pero en producción no es recomendable.
    Pues si, ambos ejemplos vuelcan a una variable, pero si que se requiere ob_end_clean() al contrario de lo que has puesto en tu línea comentada porque sino te mostrará dos veces el phpinfo una por la propia llamada a phpinfo() y otra por el echo de la variable en la que has volcado el bufer ;)

    Salu2 ;)
     
    A Administrador le gusta esto.
  9. Sphyr0

    Sphyr0 Usuario activo

    No, dijiste que error_reporting es una directiva y que, cito "eventualmente no mostrarte un error" (singular y no mostrar), y yo dije que es una directiva y ademas una funcion (cuyo valor predomina ante el de la directiva), y, cito "mostrara o no los errores" (plural y añado que segun el valor puede o no mostrar los errores).

    Reitero, con ob_start evitas que se se genere el error porque todo se almacena en el buffer: "lo corrige" (si asi lo quieres ver, pero como un quick hack y no una solucion real), porque si quitas ob_start se generara el error nuevamente. La verdadera solucion es que no se envie contenido antes que el header, asi no requieres de ob_start, error_reporting, @ ni demas anexos. Punto :cool:

    Algo asi hiciste... :confused:

    Te doy la razon :cool: (tenia la mente presionada en mi trabajo -excusas- hehe :p)
     
  10. yoseman

    yoseman Usuario activo

    No entiendo muy bien a qué te refieres con ''singular y no mostrar'', eventualmente no mostrará los errores(si te gusta más hablar en plural ;)), si haces un override de la directiva llamando a la función pues como bien dices prevalece la función, pero no entiendo, por eso dije eventualmente sobreentendiendo todas las supuestas correcciones que has posteado más tarde, como intentando corregirme diciendo lo mismo que yo y luego alegando que ''yo hable en singular y tu en plurar'' ?¿?.

    Creo que ya con esta será la 4 vez que digo que no es aconsejable usar ob_start :-D, en mi criterio, pero que realmente corrige el error(o errores). Que es mejor no usarlo pues si, porque acostumbrarte a ello, puede hacerte caer en una mala metodología, pero si por ejemplo estás programando una aplicación web en php, y necesitas en un momento puntual enviar un header tras haber enviado cabeceras, pues con esta función puedes hacerlo. Pero no es aconsejable acostumbrarse a ello, y mucho menos dejarlo ya en producción.

    Me pareció entender que me corregiste por hablar en singular, y hablas tu ahora en singular :p , qué hago te corrijo yo para decir lo mismo que dije al principio pero en plural ¿?¿ :)

    No entiendo a qué te refieres?
    Si te refieres a que si he usado ob_start(), pues te repito, que si alguna vez lo he hecho, ha sido en entornos de prueba. De hecho de la forma en que yo suelo trabajar, con mod_rewrite, es muy difícil que cometa este error, porque lo que he de hacer ante todo es recoger por get, componer la página a mostrar a partir de ahi (que a su vez se compone como ya sabes de muchas otras partes) y determinar cual es el script o los scripts a cargar, en que sección estamos, generar el menu en consecuencia, generar titulos de página, keywords etc. Y cómo te puedes imaginar si hago todo eso para mostrar una simple página, y a veces la página en sí ni siquiera existe como script .php en el servidor, ya que dependiendo del proyecto es posible que los contenidos dínamicos sólo varien en texto que el cliente puede cambiar fácilmente desde un acm, no me será muy difícil programar una función que dependiendo de la url o del factor que sea incluya un header location o algo que se haya de interpretar antes de mandar salida al navegador.

    De hecho es algo sencillísimo y que hago casi siempre, no ya sólamente para discriminar encabezados, pies de página etc por sección, sino tb para incluir por ejemplo archivos .js o .css dependiendo de cada sección. Quiero decir en realidad yo trabajo con un sólo script que suele ser index.php que es llamado siempre a través de mod_rewrite en htaccess, recogo por get la url, que suelen ser de tipo friendly urls en las que se separa por barras '/' cada variable GET a recoger, y a partir de esa url, que se puede componer y que no es necesario que exista físicamente, ya que mod_rewrite te manda a index.php, tu recoges la petición y actuas en consecuencia, cargando lo que proceda, incluyendo inicios de sesión, headers si hace falta.
    Con decirte que tengo sitios hechos en los que las secciones del portal(con su descripción de página, sus Keywords, si la página requier usuario logueado, qué privilegio necesita para ver esta sección, etc ) estan en db y cuando un cliente quiere añadir una sección no hace falta ni que suba ningún php, ya que sólo es regenrar el menu que suele ir con <ul> y <li> y si es muy extenso se puede hasta cachear cuando haya alguna modificación para no atacar a la base de datos a cada petición, con cosas que generalmente no suelen cambiar, como por ejemplo los menus.

    Todo esto ha evolucionado muchísimo, y llevamos años trabajando y a mi o a ti probablemente es muy dificil que nos suceda el tener que recurrir a ob_start, porque lo tenemos todo tan machacado y estamos 16 horas al día tecleando, trasteando php, que si mysql, que si ahora voy a crear la tabla con phpmyadmin, que si crear el connection.php, que si meter un login de usuario, que si crear las tablitas, que si implementar reenvio de claves, que si jquery, que si ahora a tocar css, que si ahora hay transciones con css3 y lo mismo paso de meter jquery, que si este cliente quiere que suene la música y no se corte al cambiar de sección, AJAX QUE TE CRIO!!! en fin que te voy a contar.

    Pero puede darse la circunstancia de que una persona no iniciada se encuentre con este problema y necesite solventarlo momentaneamente, ý puede que por alguna razón no quiera tocar la configuración de reporte de errores en cuyo caso ob_start() pues le puede servir.

    En fin que veo que estamos diciendo lo mismo los dos, en singular y/o en plural asi que dejo el tema.

    Saludos.
     
    Última edición: 10 Ene 2013
  11. yoseman

    yoseman Usuario activo

    Lo más importante creo yo es que este es un mundo fascinante y que no deja de evolucionar, empezamos a los 12 años trasteando php y usando error_reporting y ob_starts, y acabamos haciendo cosas tan complejas y sencillas a la vez que dan miedo.

    Si yo tuviese que explicarle ahora a una persona que acaba de empezar todo lo que hago automáticamente al crear un portal sin ni siquiera darme cuenta, probablemente le asustaría. Lo msimo le aconsejaría que de momento use ob_start() hasta que tenga ciertas cosas claras, aunque no sé jajajaja


    Y lo mejor de todo es que es un mundo en que siempre puedes seguir aprendiendo ;)
     
  12. Sphyr0

    Sphyr0 Usuario activo

    hmm... En verdad que esto ya sale de contexto :lol:

    Lo del plural y singular viene especificamente para el tema de error_reporting y nada mas, pues no es lo mismo que muestre/corrija/evite/etc., o no, un unico error a todos :)

    No se si debo interpretarlo como burla, "una verdadera pregunta" o simplemente te saliste por la tangente :confused:

    Nada que ver... Me referia, en concreto, por este comentario:

    Es decir, aconsejas el uso de ob_start para corregir un error que se soluciona correctamente de forma distinta y mucho mas simple, a pesar que expresaste posteriormente:

    "Claro lo que no hay que hacer es coger y decir, me da un error de headers already sents y lo soluciono con las funciones de bufer."

    En fin, he sido claro en mis mensajes y no tengo mas que aportar, hora de dormir :)
     
  13. yoseman

    yoseman Usuario activo

    Disculpa,

    Primero empezaste diciendo que no lo corrige, cosa que es radicalmente falsa, ya que si lo corrige y luego que es igual que usar error_reporting, cuando no tiene nada que ver. Y luego me dices a mi que si hablo en plural o en singular, acabas hablando tu en singular, despues de decir que está mal hablar en singular, y luego ahora dices que depende, si hablas tu puede ser como quieras, pero si hablan los demás ya eliges tu lo que está bien y lo que está mal.

    Puse una solución, pero recomendando que se puede usar en pruebas para testear algo rápidamente y no en producción, y ya van 4 veces que me dices que yo lo recomiendo. tienes algún problema de lectura o algo? O realmente es que estás intentando picarme. Porque entonces yo te diría: 'Crees que por saber como corregir la solución de cabeceras ya enviadas has demostrado que eres alguién? Porque es uno de los errores más comunes que existen, y la solución es poco menos que de dominio público.

    Luego pongo un ejemplo de uso de ob_start, y apareces tu con otro ejemplo que en realidad es el mismo, pero que encima está mal, ya que dices que no hace falta cerrar el bufer como dándotelas de listo y supervisando o autorizando el código que ponen los demás pero sin siquiera entenderlo, cuando eso tambien es radicalmente falso en el ejemplo que puse porque sino se muestra la salida dos veces, a ver una cosa es cerrar el bufer y vaciarlo sin volcarlo y otra muy distinta es cerrarlo y volcarlo, y cada función hace una cosa. Lo que pasa es que vas de listo, entras ves un código, crees saber lo que hace, acabas poniendo tu uno igual pero diciendo cosas que no son, como intentando dar a entender que estás por encima de lo que los demás posteen, pero que tu como experto das tu visto bueno, y en este caso, en vez del visto bueno metiste la pata.

    Asi que ahi te quedas, yo no pienso volver a repetir que no aconsejo usar ob_start en producción(Quinta vez que lo digo y cuarta o quinta que me vuelves a repetir que yo lo aconsejo :-¿?¿??¿) y que si se ha de usar es para probar.

    Tu obviamente, como vas de listo, volverás a entrar y a decir que yo recomiendo ob_start(), despues de haber dicho ya contadas ocasiones que no es recomendable usarlo.
    Interpretalo como quieras ese no es mi problema, pero me resulta un poco infantil, citar a los demás diciendo que si hablan en singular y hay que hablar en plural, para luego acabar tu hablando en singular, luego decir que si hablamos de directivas tenemos que hablar en plural :-?¿?¿?¿

    Bueno y si cambiamos de sitio el código que da error subiendolo antes de que se envien las cabeceras y luego lo vuelves a poner donde estaba se volvería a generar el error ;)

    Una solución es una solución, si es solución es real, otra cosa es que sea o no recomendable, o que sea mejor o peor práctica. Yo tb he dicho todo lo que debía.

    Un saludo.
     
    Última edición: 10 Ene 2013
  14. ideasmultiples

    ideasmultiples Usuario activo

    ob_start y sus derivados no son una solución ni resuelven el problema, lo ocultan.

    La corrección del problema es averiguar que se escribe y donde, normalmente algún error o un espacio perdido...

    :cool:
     
    A FanHost le gusta esto.
  15. dante6

    dante6 Nuevo usuario

    Gracias estimado Apolo, colgué en php un programa que en localhost no tiene errores (al menos en Firefox), y me lanzó el error de session_start() buscando lo pude solucionar con tus indicaciones. Acabo de inscribirme a la comunidad.
     
  16. omar231120

    omar231120 Nuevo usuario

    ami me sale este error

    Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /home/omar2311/public_html/index.php:11) in



    no se como solucionarlo pero les dejo mi codigo para que vean




    <?php require_once('Connections/swiki.php');?>
    <?php
    // *** Validate request to login to this site.
    if (!isset($_SESSION)) {
    session_start();

    }

    $loginFormAction = $_SERVER['PHP_SELF'];
    if (isset($_GET['accesscheck'])) {
    $_SESSION['PrevUrl'] = $_GET['accesscheck'];
    }

    if (isset($_POST['id_email'])) {
    $loginUsername=$_POST['id_email'];
    $password=$_POST['id_contraseña'];
    $MM_fldUserAuthorization = "";
    $MM_redirectLoginSuccess = "usuario.php";
    $MM_redirectLoginFailed = "acceso_error.php";
    $MM_redirecttoReferrer = false;
    mysql_select_db($database_swiki, $swiki);

    $LoginRS__query=sprintf("SELECT id_email, `id_contraseña` FROM tabla_usuario WHERE id_email=%s AND `id_contraseña`=%s",
    GetSQLValueString($loginUsername, "text"), GetSQLValueString($password, "-1"));

    $LoginRS = mysql_query($LoginRS__query, $swiki) or die(mysql_error());
    $loginFoundUser = mysql_num_rows($LoginRS);
    if ($loginFoundUser) {
    $loginStrGroup = "";

    if (PHP_VERSION >= 5.1) {session_regenerate_id(true);} else {session_regenerate_id();}
    //declare two session variables and assign them
    $_SESSION['MM_Username'] = $loginUsername;
    $_SESSION['MM_UserGroup'] = $loginStrGroup;

    if (isset($_SESSION['PrevUrl']) && false) {
    $MM_redirectLoginSuccess = $_SESSION['PrevUrl'];
    }
    header("Location: " . $MM_redirectLoginSuccess );
    }
    else {
    header("Location: ". $MM_redirectLoginFailed );
    }
    }
    ?>


    <form id="acceso" name="form1" method="POST" action="<?php echo $loginFormAction;?>">
    <p>Email:
    <label for="id_email"></label>
    <input type="text" name="id_email" id="id_email" />
    </p>
    <p>Contraseña:
    <label for="id_contraseña"></label>
    <input type="text" name="id_contraseña" id="id_contraseña" />
    </p>
    <p>
    <input type="submit" name="button" id="button" value="Entrar" />
    </p>
    </form>
     
  17. justice13

    justice13 Usuario activo

    Aunque no tengo respuesta a tu problema, te doy un consejo...

    JAMÁS publiques el nombre de usuario que empleas en una cuenta (sea hosting, o superiores). Es un riesgo de seguridad para ti ;-)

    Espero tengas suerte y obtengas una solución.

    Salu2,
     
  18. guitobon

    guitobon Usuario activo

    Te falla la consulta SQL. Entonces se muestra el error por pantalla (ya se manda algo de salida).
    Una vez pasa esto, ya no puedes usar la funcion header.

    Pista: en SQL las cadenas se encierran entre comillas ;-)

     
    Última edición: 11 Abr 2013


Alojamiento web, Hosting Reseller, Servidores Dedicados - All in Hosting


    
    
    
    
Blog · Sitios amigos: GuiaHosting · Unidominios · Interalta ·