PDA

Visualizza la versione completa : Perché è sbagliato usare ob_start() con "Warning: Cannot modify header information - headers already sent by"?


giannino1995
17-04-2016, 23:58
Ho letto questa discussione:
http://forum.html.it/forum/showthread.php?threadid=1449517
dove si trova una soluzione per il problema:
"Warning: Cannot modify header information - headers already sent by"
Nella discussione c'è scritto che l'header() deve essere la prima direttiva php della pagina e fin qui tutto chiaro però se io voglio realizzare una pagina in cui desidero:
1) fare il login ed il logout;
2) scrivere i record nel database e usare il database aggiornato per riscrivere i tag nella pagina stessa;
3) cancellare i record dal database ed automaticamente aggiornare i tag scritti al punto 2;
come faccio a non usare ob_start() per evitare il problema?
Detto in altro modo come faccio a dire a php di ritornare nella stessa pagina senza infrangere la regola che l'header debba essere la prima istruzione?
Se sono nella pagina prova.php e ci voglio ritornare perché ho premuto su qualche tag è chiaro che l'header non può essere la prima istruzione perché il pulsante è un tag. Come posso ritornare nella stessa pagina rileggendo la pagina stessa dall'inizio?
Grazie

clasku
18-04-2016, 08:11
[...]l'header() deve essere la prima direttiva php della pagina[...]
no, deve essere invocato prima che sia inviato qualsiasi output
puoi scrivere 100.000 righe di codice e alla fine mettere mettere la chiamata a header(), l'importante è che tu non abbia effettuato alcun output verso il browser (echo, print_r, print, var_dump, ecc)

camionistaxcaso
18-04-2016, 10:04
Quello che non ho mai capito è come fa a funzionare se fai un print in un file e subito dopo usi l' header("Location") in un file incluso nello stesso. Li legge separatamente e nel caso di una redirect annulla il print iniziale? Sono confuso.

.Kurt
18-04-2016, 11:59
Li legge separatamente e nel caso di una redirect annulla il print iniziale?
La domanda non è molto chiara.. puoi riformulare?


come faccio a non usare ob_start() per evitare il problema?
Strutturando bene la pagina, evitando di mescolare la logica dell'applicazione con la sua presentazione. Se ti poni questo problema è probabile che scrivi ancora molti spaghetti code.

camionistaxcaso
18-04-2016, 12:12
La domanda non è molto chiara.. puoi riformulare?



Ok ritento...perchè così funziona?


//File' s name: index.php
print "In questo file eseguo un output...dopo di che includo il file contents.php che fa la redirect...";
include("./contents.php");

Contenuto di contents.php


// File' s name: contents.php
//Esegue tranquillamente la redirect anche se è stato fatto l' output in index.php
header("Location: index.php");

Facendo l' inclusione non è come se fosse diventato un unico file per la logica del non fare output prima della redirect?

.Kurt
18-04-2016, 12:29
php ha una opzione che puoi configurare nel php.ini che si chiama "output_buffering (http://php.net/manual/en/outcontrol.configuration.php#ini.output-buffering)". Attivandola, quando invii un output php non lo invierà immediatamente al web server, per cui anche inviando un `header` successivamente non causerà un errore. Considera questa soluzione come un workaround, visto che il corretto funzionamento del tuo script dipende da come è stato configurato l'ambiente in cui fai girare il tuo sito.

camionistaxcaso
18-04-2016, 13:01
ma io non credo di aver mai scritto codice con quell' opzione attivata, perchè mi è sempre capitato di ricevere l' errore

giannino1995
18-04-2016, 13:45
1) Quindi se io a fine pagina scrivo questo:


<form method="post" action="?logout" class="gestione-news">
<input type="submit" value="Effettua il logout"/>
</form>
<?php
if (isset($_GET['logout']))
{
$_SESSION = array();
session_destroy();
header('Location: /bacheca/pannello.php');
exit();
}
?>

commetto un errore oppure no?
2) Se riscrivo tutta la mia pagina in questo modo:

<?php
header ( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
header ( "Cache-Control: no-cache" );
header ( "Pragma: no-cache" );
?>
<?php session_start(); ?>
include 'codice.php';
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8">
...
</head>
avendo cura di mettere tutto il codice dentro codice.php, header compresi, la logica sarebbe corretta oppure no?
Grazie

k.b
18-04-2016, 14:03
1) si commetti un errore, d'altra parte che senso ha stampare cose se tanto fai una redirezione e non e' possibile leggerle?

2) idealmente PHP e HTML vanno fisicamente in file separati, nel primo tutta la logica del tuo script (quello che deve fare e le decisioni che deve prendere) e nel secondo solo il markup HTML con la sola aggiunta di sostituizioni di variabili e un minimo di strutture di controllo ad esse collegate (foreach, if e poco altro), ancora meglio se usi un templating engine

camionistaxcaso
18-04-2016, 18:25
Potrebbe essere una buona pratica puntare sempre ad un file php che fa qualcosa e poi redirect alla pagina che effettua l' output? Però ci sarebbe uno scambio in più tra server e client...

Loading