Al ejecutar mi script, recibo varios errores como este:
Advertencia: No se puede modificar la información del encabezado: los encabezados ya enviados por ( salida iniciada en /some/file.php:12 ) en /some/file.php en la línea 23
Las líneas mencionadas en los mensajes de error contienen header()
y setcookie()
llamadas.
¿Cuál podría ser la razón de ésto? ¿Y como arreglarlo?
ob_start
yob_end_clean()
puede resultar útil aquí). Luego puede establecer una cookie o sesión igual aob_get_contents()
y luego usarob_end_clean()
para borrar el búfer.safeRedirect
función en mi biblioteca PHP: github.com/heinkasner/PHP-Library/blob/master/extra.phpUTF-8
, peroUTF-8 (Without BOM)
~~~~~~~~~~~Respuestas:
¡No hay salida antes de enviar encabezados!
Las funciones que envían / modifican encabezados HTTP deben invocarse antes de realizar cualquier salida . summary ⇊ De lo contrario, la llamada falla:
Algunas funciones que modifican el encabezado HTTP son:
header
/ /header_remove
session_start
/ /session_regenerate_id
setcookie
/ /setrawcookie
La salida puede ser:
Involuntario:
<?php
o después?>
Intencional:
print
,echo
Y otras funciones de salida de la producción de<html>
Secciones en bruto<?php
código anterior .¿Por que sucede?
Para comprender por qué los encabezados deben enviarse antes de la salida, es necesario observar una respuesta HTTP típica . Los scripts PHP generan principalmente contenido HTML, pero también pasan un conjunto de encabezados HTTP / CGI al servidor web:
La página / salida siempre sigue a los encabezados. PHP tiene que pasar los encabezados al servidor web primero. Solo puede hacer eso una vez. Después del doble salto de línea, nunca más podrá enmendarlos.
Cuando PHP recibe la primera salida (
print
,echo
,<html>
) se lave todos los encabezados recogidos. Luego puede enviar toda la salida que desee. Pero enviar más encabezados HTTP es imposible entonces.¿Cómo puede averiguar dónde se produjo la salida prematura?
La
header()
advertencia contiene toda la información relevante para localizar la causa del problema:Aquí "línea 100" se refiere al script donde falló la
header()
invocación .La nota " salida iniciada en " entre paréntesis es más significativa. Se denomina la fuente de salida anterior. En este ejemplo es
auth.php
y línea52
. Ahí es donde tenía que buscar resultados prematuros.Causas típicas:
Impresión, eco
La salida intencional de
print
yecho
declaraciones terminará la oportunidad de enviar encabezados HTTP. El flujo de la aplicación debe ser reestructurado para evitar eso. Usar funciones y esquemas de plantillas. Asegúrese de queheader()
ocurran llamadas antes de que se escriban los mensajes.Las funciones que producen resultados incluyen
print
,echo
,printf
,vprintf
trigger_error
`ob_flush
`ob_end_flush
`var_dump
`print_r
readfile
`passthru
`flush
`imagepng
`imagejpeg
entre otros y funciones definidas por el usuario.
Áreas HTML sin procesar
Las secciones HTML no analizadas en un
.php
archivo también son salida directa. Las condiciones del script que activarán unaheader()
llamada deben anotarse antes de cualquier<html>
bloque sin procesar .Use un esquema de plantillas para separar el procesamiento de la lógica de salida.
Espacio en blanco antes
<?php
para las advertencias "script.php line 1 "Si la advertencia se refiere a la salida en línea
1
, entonces se trata principalmente de espacios en blanco , texto o HTML antes del<?php
token de apertura .Del mismo modo, puede ocurrir para scripts o secciones de scripts anexados:
PHP en realidad come un solo salto de línea después de cerrar las etiquetas. Pero no compensará múltiples líneas nuevas, pestañas o espacios desplazados a tales huecos.
UTF-8 BOM
Los saltos de línea y los espacios solos pueden ser un problema. Pero también hay secuencias de caracteres "invisibles" que pueden causar esto. La más famosa es la UTF-8 BOM (Byte-Order-Mark) que no se muestra en la mayoría de los editores de texto. Es la secuencia de bytes
EF BB BF
, que es opcional y redundante para documentos codificados UTF-8. Sin embargo, PHP tiene que tratarlo como salida sin procesar. Puede aparecer como caracteres
en la salida (si el cliente interpreta el documento como Latin-1) o "basura" similar.En particular, los editores gráficos y los IDE basados en Java son ajenos a su presencia. No lo visualizan (obligado por el estándar Unicode). Sin embargo, la mayoría de los editores de consola y programadores:
Ahí es fácil reconocer el problema desde el principio. Otros editores pueden identificar su presencia en un menú de archivo / configuración (Notepad ++ en Windows puede identificar y solucionar el problema ). Otra opción para inspeccionar la presencia de BOM es recurrir a un editor hexadecimal . En los sistemas * nix
hexdump
generalmente está disponible, si no una variante gráfica que simplifica la auditoría de estos y otros problemas:Una solución fácil es configurar el editor de texto para guardar archivos como "UTF-8 (sin BOM)" o una nomenclatura similar. A menudo, los recién llegados recurren a la creación de nuevos archivos y simplemente copian y pegan el código anterior nuevamente.
Utilidades de corrección
También hay herramientas automatizadas para examinar y reescribir archivos de texto (
sed
/awk
orecode
). Para PHP específicamente, está laphptags
etiqueta tidier . Reescribe las etiquetas cercanas y abiertas en formas largas y cortas, pero también corrige fácilmente los problemas de espacios en blanco iniciales y finales, Unicode y UTF-x BOM:Es sensato usarlo en un directorio completo de inclusión o proyecto.
Espacio en blanco después
?>
Si la fuente del error se menciona detrás del cierre,
?>
entonces es donde se escribieron algunos espacios en blanco o texto sin formato. El marcador final de PHP no termina la ejecución del script en este punto. Los caracteres de texto / espacio después de esto se escribirán como contenido de la página todavía.Se recomienda comúnmente, en particular a los recién llegados, que
?>
se omitan las etiquetas de cierre de PHP al final . Esto evita una pequeña porción de estos casos. (Muy comúnmente losinclude()d
guiones son los culpables).Fuente de error mencionada como "Desconocido en la línea 0"
Por lo general, es una configuración de extensión de PHP o php.ini si no se concreta ninguna fuente de error.
gzip
configuración de codificación de flujo o elob_gzhandler
.extension=
módulo doblemente cargado que genere un mensaje implícito de inicio / advertencia de PHP.Mensajes de error anteriores
Si otra declaración o expresión de PHP hace que se imprima un mensaje o aviso de advertencia, eso también cuenta como salida prematura.
En este caso, debe evitar el error, retrasar la ejecución de la declaración o suprimir el mensaje con, por ejemplo,
isset()
o@()
cuando no obstruya la depuración más adelante.Sin mensaje de error
Si tiene
error_reporting
odisplay_errors
deshabilitado porphp.ini
, entonces no aparecerá ninguna advertencia. Pero ignorar los errores no hará que el problema desaparezca. Los encabezados aún no se pueden enviar después de una salida prematura.Entonces, cuando las
header("Location: ...")
redirecciones fallan silenciosamente, es muy recomendable buscar advertencias. Vuelva a habilitarlos con dos comandos simples sobre el script de invocación:O
set_error_handler("var_dump");
si todo lo demás falla.Hablando de encabezados de redireccionamiento, a menudo debes usar un modismo como este para las rutas de código finales:
Preferiblemente, incluso una función de utilidad, que imprime un mensaje de usuario en caso de
header()
fallas.Búfer de salida como solución alternativa
El almacenamiento en búfer de salida de PHP es una solución alternativa para aliviar este problema. A menudo funciona de manera confiable, pero no debe sustituir la estructuración adecuada de la aplicación y la separación de la salida de la lógica de control. Su propósito real es minimizar las transferencias fragmentadas al servidor web.
Sin
output_buffering=
embargo, la configuración puede ayudar. Configúrelo en php.ini o mediante .htaccess o incluso .user.ini en configuraciones modernas de FPM / FastCGI.Habilitarlo permitirá que PHP almacene la memoria intermedia en lugar de pasarla al servidor web al instante. PHP, por lo tanto, puede agregar encabezados HTTP.
También se puede activar con una llamada para
ob_start();
encima de la secuencia de comandos de invocación. Lo que, sin embargo, es menos confiable por múltiples razones:Incluso si
<?php ob_start(); ?>
comienza el primer script, es posible que antes se barajen espacios en blanco o una lista de materiales, lo que lo hace ineficaz .Puede ocultar espacios en blanco para la salida HTML. Pero tan pronto como la lógica de la aplicación intente enviar contenido binario (una imagen generada, por ejemplo), la salida externa almacenada en búfer se convierte en un problema. (Necesaria
ob_clean()
como una solución alternativa).El búfer tiene un tamaño limitado y puede desbordarse fácilmente cuando se deja el valor predeterminado. Y tampoco es una ocurrencia rara, difícil de rastrear cuando sucede.
Por lo tanto, ambos enfoques pueden volverse poco confiables, en particular cuando se cambia entre configuraciones de desarrollo y / o servidores de producción. Es por eso que el búfer de salida se considera ampliamente solo una muleta / estrictamente una solución.
Vea también el ejemplo de uso básico en el manual, y para más ventajas y desventajas:
¿Pero funcionó en el otro servidor?
Si no recibió la advertencia de encabezados antes, entonces la configuración de php.ini de búfer de salida ha cambiado. Es probable que no esté configurado en el servidor actual / nuevo.
Comprobando con
headers_sent()
Siempre puede usar
headers_sent()
para sondear si aún es posible ... enviar encabezados. Lo cual es útil para imprimir condicionalmente una información o aplicar otra lógica de respaldo.Las soluciones alternativas útiles son:
<meta>
Etiqueta HTMLSi su aplicación es estructuralmente difícil de arreglar, entonces una forma fácil (pero poco profesional) de permitir redirecciones es inyectando una
<meta>
etiqueta HTML . Se puede lograr una redirección con:O con un breve retraso:
Esto conduce a HTML no válido cuando se utiliza más allá de la
<head>
sección. La mayoría de los navegadores aún lo aceptan.Redireccionamiento de JavaScript
Como alternativa, se puede utilizar una redirección de JavaScript para las redirecciones de página:
Si bien esto a menudo es más compatible con HTML que la
<meta>
solución alternativa, incurre en una dependencia de clientes con capacidad JavaScript.Sin embargo, ambos enfoques hacen retrocesos aceptables cuando fallan las llamadas genuinas de encabezado HTTP (). Idealmente, siempre combinaría esto con un mensaje fácil de usar y un enlace en el que se pueda hacer clic como último recurso. (Que, por ejemplo, es lo que hace la extensión http_redirect () PECL).
Por qué
setcookie()
ysession_start()
también se ven afectadosAmbos
setcookie()
ysession_start()
necesitan enviar unSet-Cookie:
encabezado HTTP. Por lo tanto, se aplican las mismas condiciones, y se generarán mensajes de error similares para situaciones de salida prematuras.(Por supuesto, también se ven afectados por las cookies deshabilitadas en el navegador, o incluso por problemas de proxy. La funcionalidad de la sesión obviamente también depende del espacio libre en el disco y otras configuraciones de php.ini, etc.)
Enlaces adicionales
fuente
?>
desde el final de un archivo php suele ser una buena práctica que también ayuda a minimizar estos errores. Los espacios en blanco no deseados no aparecerán al final de los archivos, y aún podrá agregar encabezados a la respuesta más adelante. También es útil si usa el búfer de salida, y no le gustaría ver espacios en blanco no deseados agregados al final de las partes generadas por los archivos incluidos.Este mensaje de error se activa cuando se envía algo antes de enviar encabezados HTTP (con
setcookie
oheader
). Las razones comunes para generar algo antes de los encabezados HTTP son:Espacio en blanco accidental, a menudo al principio o al final de los archivos, como este:
Para evitar esto, simplemente omita el cierre
?>
; de todos modos, no es obligatorio.3F 3C
. Puede eliminar de forma segura la listaEF BB BF
de materiales desde el inicio de los archivos.echo
,printf
,readfile
,passthru
, código antes<?
etc.display_errors
propiedad php.ini. En lugar de fallar en un error del programador, php corrige silenciosamente el error y emite una advertencia. Si bien puede modificar las configuraciones de informe de errordisplay_errors
o error , debería solucionar el problema.Las razones comunes son los accesos a elementos indefinidos de una matriz (como
$_POST['input']
sin usarempty
oisset
para probar si la entrada está configurada), o usando una constante indefinida en lugar de un literal de cadena (como en$_POST[input]
, observe las comillas faltantes).Activar el búfer de salida debería hacer que el problema desaparezca; toda la salida después de la llamada a
ob_start
se almacena en la memoria intermedia hasta que libere el búfer, por ejemplo, conob_end_flush
.Sin embargo, aunque el almacenamiento en búfer de salida evita los problemas, realmente debe determinar por qué su aplicación genera un cuerpo HTTP antes del encabezado HTTP. Eso sería como atender una llamada telefónica y discutir su día y el clima antes de decirle a la persona que llama que tiene el número equivocado.
fuente
Recibí este error muchas veces antes, y estoy seguro de que todos los programadores de PHP tuvieron este error al menos una vez antes.
Posible solución 1
Este error puede haber sido causado por los espacios en blanco antes del inicio del archivo o después del final del archivo. Estos espacios en blanco no deberían estar aquí.
ex) NO DEBE HABER ESPACIOS EN BLANCO AQUÍ
Verifique todos los archivos asociados con el archivo que causa este error.
Nota: Algunas veces EDITOR (IDE) como gedit (un editor de Linux predeterminado) agrega una línea en blanco en el archivo de guardado. Esto no debería suceder. Si estás usando Linux. puede usar el editor VI para eliminar espacios / líneas después de?> al final de la página.
Posible solución 2: si este no es su caso, utilice ob_start para generar el almacenamiento en búfer:
Esto activará el almacenamiento en búfer de salida y sus encabezados se crearán después de que la página esté almacenada.
fuente
ob_start()
simplemente oculta el problema; No lo use para resolver este problema en particular.ob_start()
, entonces qué debo hacer para resolver este problema:Headers already sent
ob_start()
no "oculta" el problema, lo resuelve .En lugar de la línea de abajo
escribir
o
Definitivamente resolverá tu problema. Me enfrenté al mismo problema pero lo resolví escribiendo la ubicación del encabezado de la manera anterior.
fuente
Tú lo haces
antes de configurar las cookies, lo cual no está permitido. No puede enviar ningún resultado antes de los encabezados, ni siquiera una línea en blanco.
fuente
Es por esta línea:
No debe imprimir / repetir nada antes de enviar los encabezados.
fuente
PROBLEMAS COMUNES:
(copiado de: fuente )
====================
1) no debe haber ninguna salida (es decir,
echo..
o códigos HTML) antes delheader(.......);
comando.2) elimine cualquier espacio en blanco (o nueva línea ) antes
<?php
y después de las?>
etiquetas.3) REGLA DE ORO! - compruebe si ese archivo php (y también, si tiene
include
otros archivos) tiene UTF8 sin codificación BOM (y no solo UTF-8 ). ¡Eso es un problema en muchos casos (porque el archivo codificado UTF8 tiene un carácter especial al comienzo del archivo php, que su editor de texto no muestra) !!!!!!!!!!!4) Después de
header(...);
usarexit;
5) use siempre la referencia 301 o 302:
6) Active el informe de errores y encuentre el error. Su error puede ser causado por una función que no funciona. Cuando activa el informe de errores, siempre debe corregir primero el error superior. Por ejemplo, podría ser "Advertencia: date_default_timezone_get (): no es seguro confiar en la configuración de la zona horaria del sistema". - luego más abajo puede ver el error "encabezados no enviados". Después de corregir el error superior (primero), vuelva a cargar su página. Si todavía tiene errores, vuelva a corregir el error superior.
7) Si nada de lo anterior ayuda, use la redirección JAVSCRIPT (sin embargo, es un método muy no recomendado), puede ser la última oportunidad en casos personalizados ...:
fuente
301
o302
importante?Un consejo simple: ¡Un espacio simple (o carácter especial invisible) en su script, justo antes de la primera
<?php
etiqueta, puede causar esto! Especialmente cuando está trabajando en un equipo y alguien está usando un IDE "débil" o ha desordenado los archivos con editores de texto extraños.He visto estas cosas;)
fuente
Otra mala práctica puede invocar este problema que aún no se ha establecido.
Ver este fragmento de código:
Las cosas están bien, ¿verdad?
¿Qué pasa si "a_important_file.php" es esto:
¿Esto no funcionará? ¿Por qué ?, porque ya se genera una nueva línea.
Ahora, aunque este no es un escenario común, ¿qué sucede si está utilizando un marco MVC que carga muchos archivos antes de transferir cosas a su controlador? Este no es un escenario poco común. Prepárate para esto.
Desde PSR-2 2.2:
Unix LF (linefeed) line ending
.single blank line
.omitted
de archivos que contenganonly php
Créeme, seguir estos estándares puede ahorrarte muchísimas horas de tu vida :)
fuente
?>
etiqueta de cierre en ningún archivo de ninguna manera, de ninguna maneraCR LF
(final de línea típico de Windows). Lo resuelvo descargando el archivo original del repositorio de Wordpress que tieneLF
(fin de línea de Linux) en lugar deCR LF
y también moví mi función a las funciones del tema.php. Basado en: bit.ly/1Gh6mzN?>
<?php
, eliminando y agregando una sola línea en blanco, agregando y omitiendo la etiqueta de cierre?>
. En Windows + Wamp, todas esas combinaciones funcionan bien. Wierd ...A veces, cuando el proceso de desarrollo tiene estaciones de trabajo WIN y sistemas LINUX (hosting) y en el código no ve ningún resultado antes de la línea relacionada, podría ser el formato del archivo y la falta de final de línea Unix LF (salto de línea ) .
Lo que solemos hacer para solucionarlo rápidamente es cambiar el nombre del archivo y, en el sistema LINUX, crear un nuevo archivo en lugar del renombrado y luego copiar el contenido en él. Muchas veces esto resuelve el problema ya que algunos de los archivos que se crearon en WIN una vez que se movieron al hosting causan este problema.
Esta solución es una solución fácil para los sitios que administramos por FTP y, a veces, puede salvar a nuestros nuevos miembros del equipo en algún momento.
fuente
En general, este error surge cuando enviamos el encabezado después de hacer eco o imprimir. Si este error surge en una página específica, asegúrese de que la página no haga eco antes de llamar
start_session()
.Ejemplo de error impredecible:
Un ejemplo más:
Conclusión: no muestre ningún carácter antes de llamar
session_start()
oheader()
funciones, ni siquiera un espacio en blanco o una nueva líneafuente