W3docs

Funzione PHP headers_sent(): tutto quello che devi sapere

Come sviluppatore PHP, potresti dover verificare se gli header HTTP sono già stati inviati al client. headers_sent() è una funzione built-in di PHP.

Ogni risposta HTTP è divisa in due parti: un blocco di header (codice di stato, Content-Type, cookie, redirect) seguito dal corpo della risposta. Il problema è che gli header devono essere inviati prima di qualsiasi output nel corpo. Nel momento in cui PHP emette un singolo byte nel corpo, scarica gli header e li blocca — qualsiasi chiamata successiva a header(), setcookie() o session_start() genera il famigerato avviso Cannot modify header information - headers already sent.

headers_sent() è la funzione built-in che ti permette di verificare, prima di tentare di inviare un header, se è già troppo tardi. Questa guida ne descrive la sintassi, i parametri per riferimento, le cause dell'output prematuro e come risolverle.

Cosa fa headers_sent()

headers_sent() restituisce un valore boolean:

  • true — gli header sono già stati inviati (l'output è iniziato). Qualsiasi ulteriore chiamata a header() / setcookie() fallirà.
  • false — nessun output è ancora iniziato, quindi è ancora sicuro impostare gli header.

Proteggere la logica degli header con headers_sent() ti consente di evitare l'avviso e gestire la situazione in modo elegante (ad esempio, registrando il problema o ricorrendo a un redirect JavaScript) invece di bloccare la pagina.

Sintassi

headers_sent(string &$filename = null, int &$line = null): bool

Entrambi i parametri sono facoltativi e passati per riferimento. Quando gli header sono stati inviati, PHP li compila con la posizione dell'output che li ha causati:

  • $filename — il nome del file sorgente in cui l'output è iniziato.
  • $line — il numero di riga all'interno di quel file.

Questo è ciò che rende headers_sent() così utile per il debug: ti indica direttamente il punto incriminato.

Utilizzo di base

Controlla il valore restituito prima di inviare un header:

<?php

if (!headers_sent()) {
    header('Location: /dashboard');
    exit;
}

echo 'Headers were already sent, cannot redirect via HTTP.';

Se l'output non è ancora iniziato, viene inviato l'header di redirect. In caso contrario, lo script evita l'avviso fatale e stampa un messaggio di fallback.

Trovare dove è iniziato l'output

Passa le due variabili per riferimento per scoprire esattamente cosa ha inviato gli header — fondamentale quando uno spazio o un echo indesiderato è nascosto in un file incluso:

<?php

if (headers_sent($file, $line)) {
    echo "Headers already sent in $file on line $line";
} else {
    setcookie('theme', 'dark');
    echo 'Cookie set successfully.';
}

Se la condizione è vera, si ottiene un messaggio come Headers already sent in /var/www/header.php on line 12, che indica con precisione dove cercare.

Cosa causa "Headers Already Sent"

Qualsiasi cosa produca output nel corpo prima della chiamata all'header scarica gli header. Cause comuni:

  • Spazi bianchi o una riga vuota prima di <?php — anche uno spazio o un a capo conta come output.
  • Un a capo dopo il tag di chiusura ?> di un file incluso. (Buona pratica: omettere il tag di chiusura ?> nei file puramente PHP.)
  • echo, print, printf o var_dump eseguiti prima dell'header.
  • Un file UTF-8 salvato con BOM (byte-order mark) — quei byte iniziali invisibili sono output.
  • Avvisi/notice PHP stampati sulla pagina (quando display_errors è attivo) prima degli header.

Correggere con il buffer di output

Se non puoi riordinare il codice in modo che tutti gli header vengano prima, racchiudi lo script in un buffer di output. ob_start() mantiene il corpo in memoria invece di inviarlo immediatamente, così gli header rimangono modificabili fino allo svuotamento del buffer:

<?php

ob_start();              // start buffering — nothing is sent yet

echo 'Some early output';

// Still safe: the echo above is held in the buffer, headers are not sent
setcookie('user', 'jane');
header('X-App-Version: 2.0');

ob_end_flush();          // now send headers, then the buffered body

Poiché l'output è nel buffer, headers_sent() restituirebbe ancora false dopo l'echo, e le successive chiamate a setcookie() e header() avranno successo.

Funzioni correlate

  • header() — invia un header HTTP grezzo.
  • headers_list() — elenca gli header in coda o già inviati.
  • setcookie() — imposta un cookie (invia un header Set-Cookie).
  • ob_start() — avvia il buffer di output per ritardare l'invio degli header.
  • PHP Sessionssession_start() invia anch'essa header ed è un trigger frequente.

Conclusione

headers_sent() è una guardia piccola ma essenziale: chiamala prima di qualsiasi header(), setcookie() o session_start() per verificare se l'output è già iniziato. Quando restituisce true, gli argomenti per riferimento $filename e $line individuano l'output incriminato così puoi correggerlo — oppure racchiudi lo script in ob_start() per mantenere gli header modificabili fino a quando sei pronto a svuotare il buffer.

Pratica

Pratica
Cosa può causare l'avviso 'headers already sent' in PHP?
Cosa può causare l'avviso 'headers already sent' in PHP?
Was this page helpful?