Funzioni di controllo output PHP: tutto quello che devi sapere
Impara il buffering dell'output PHP e le funzioni ob_*: ob_start, ob_get_clean, ob_end_flush, callback ed errori comuni, con esempi eseguibili.
Normalmente, ogni echo, print o porzione di HTML in uno script PHP viene inviata al browser nel momento in cui viene eseguita. Il buffering dell'output consente di intercettare quell'output e tenerlo in memoria (un buffer) invece di inviarlo subito, in modo da poterlo ispezionare, modificare, scartare o inviare in un secondo momento. Le funzioni di controllo output di PHP sono gli strumenti integrati che gestiscono questo buffer.
Questo capitolo spiega cos'è il buffering dell'output, perché risolve problemi reali e come funziona ogni funzione ob_* — con esempi eseguibili.
Perché il buffering dell'output è importante
Il buffering dell'output è più di una curiosità. Risolve una serie di problemi PHP comuni:
- Evitare gli errori "headers already sent". In PHP devi chiamare
header()esetcookie()prima che qualsiasi output raggiunga il browser. Mettere in buffer l'output ti permette di inviare ancora gli header dopo che i tuoi template sono stati eseguiti, perché nulla è stato effettivamente inviato. Vedi headers_sent(). - Catturare l'output come stringa. Renderizza un template o includi un file e ottieni il risultato come variabile invece di stamparlo — la base della maggior parte dei semplici motori di templating.
- Post-elaborare l'intera pagina. Minimizza l'HTML, sostituisci segnaposto o comprimi l'output (gzip) in un unico posto prima che venga inviato.
- Scartare output indesiderato. Elimina il rumore da una libreria di terze parti o un'istruzione di debug che non vuoi mostrare all'utente.
Le funzioni di controllo output
Ecco le funzioni che userai di più. Operano tutte sul buffer avviato da ob_start().
| Funzione | Cosa fa |
|---|---|
ob_start() | Avvia un nuovo buffer di output. La cattura inizia da questo punto. |
ob_get_contents() | Restituisce il contenuto attuale del buffer senza interrompere il buffering. |
ob_get_length() | Restituisce il numero di byte attualmente nel buffer. |
ob_get_level() | Restituisce il livello di nidificazione (quanti buffer sono impilati). |
ob_clean() | Svuota il buffer ma mantiene il buffering attivo. |
ob_get_clean() | Restituisce il contenuto e disattiva il buffer — una combinazione comune. |
ob_end_clean() | Scarta il buffer e disattiva il buffering (non restituisce nulla). |
ob_flush() / ob_end_flush() | Invia il buffer al browser; ob_end_flush() interrompe anche il buffering. |
Catturare l'output come stringa
L'uso più comune del buffering è catturare quello che un blocco di codice stampa e memorizzarlo in una variabile. ob_get_clean() restituisce il buffer e interrompe il buffering in una sola chiamata:
Nulla raggiunge il browser fino all'echo finale, che stampa HELLO, WORLD!. Abbiamo catturato il testo, lo abbiamo trasformato e solo allora lo abbiamo inviato. Questo è esattamente come funziona una piccola funzione template:
<?php
function renderTemplate(string $name): string {
ob_start();
echo "Hello, $name!";
return ob_get_clean(); // contents + stop buffering
}
echo renderTemplate("Ada");Questo stampa Hello, Ada!. In un progetto reale il blocco in buffer sarebbe un template HTML completo con tag <?= $name ?> incorporati.
Inviare il buffer al browser
Quando vuoi solo ritardare l'output (non catturarlo), usa ob_end_flush() per inviare tutto in una volta:
Mentre il buffer è aperto puoi anche ispezionarlo con ob_get_length() e ob_get_level():
<?php
ob_start();
echo "buffered text";
echo "\nLevel: " . ob_get_level(); // 1 — one buffer is active
echo "\nLength: " . ob_get_length(); // bytes captured so far
ob_end_flush();ob_get_level() restituisce 1 perché un singolo buffer è attivo; se chiami ob_start() di nuovo al suo interno, il livello diventa 2 (i buffer si annidano come una pila).
Trasformare l'output con una callback
ob_start() accetta una callback che riceve l'intero buffer e restituisce la versione modificata. Così funzionano i minificatori di output e i filtri trova-e-sostituisci:
<?php
ob_start(function (string $buffer): string {
return str_replace("cat", "dog", $buffer);
});
echo "I have a cat.";
ob_end_flush();La callback viene eseguita quando il buffer viene inviato, quindi la pagina stampa I have a dog.. Lo stesso schema alimenta ob_gzhandler, la callback integrata di PHP per la compressione gzip dell'output.
Errori comuni
- Chiudi sempre ciò che apri. Ogni
ob_start()deve essere abbinato a una chiamata flush o clean. Un buffer non bilanciato lascia l'output bloccato in memoria e non raggiunge mai l'utente. - I buffer si annidano. Ogni
ob_start()aggiunge un livello.ob_get_clean()chiude solo quello più interno; usaob_get_level()in un ciclo se devi svuotarne più di uno. ob_get_contents()non interrompe il buffering — solo le funzioni*_cleane*_end_*lo fanno. Confonderle è una fonte frequente di output duplicato.- Un buffer ha una dimensione finita. Per impostazione predefinita PHP svuota automaticamente quando il buffer raggiunge i byte
output_buffering(php.ini), quindi non fare affidamento su di esso per contenere una quantità illimitata di dati.
Conclusione
Il buffering dell'output ti dà il controllo su quando e come l'output del tuo script viene inviato. Usalo per catturare contenuto renderizzato come stringa, per impostare header dopo aver generato una pagina, per scartare output indesiderato o per post-elaborare l'intera risposta in un unico posto. Una volta che hai capito il ciclo start/get/clean/flush, la famiglia ob_* è piccola e prevedibile.
Letture correlate: echo e print, PHP header(), PHP Sessions e PHP Cookies.