Redirect dopo un'operazione sul database (alternativo a header ("Location:..."))

In riferimento alla guida presente sul sito che suggerisce il reindirizzamento del browser dopo un'inserimento nel database per evitare che un refresh accidentale possa inviare nuovamente la query, vorrei trovare un metodo diverso per effettuare tale reindirizzamento dato che prima della chiamata header c'è già dell'output html.

non posso evitare di generare l'output (o non vedo come fare) dato che lo script si muove all'interno di un sistema a template.

Il manuale di php suggerisce l'uso di ob_start ma non ho capito come funziona, e poi mi chiedevo se usarlo per tutto lo script non lo rallentasse troppo... suggerimenti?

inviato 9 anni fa
arjuna
X 0 X

Per evitare il problema del possibile reinserimento di uno o più record nel database a seguito del reinvio di un post ci sono 2 strade:

1) impedire il reinvio del POST, ovvero effettuare un redirect dopo aver inserito i dati nel DB. In questo caso la pagina non può produrre output, in nessun modo, neanche con le funzioni di buffering dell'output (ob_start&C.). Tutto l'output deve essere generato dalla pagina alla quale viene reindirizzato l'utente, attraverso divese tecniche. Quella mostrata nel corso usa una stringa passata via GET. Si possono usare anche le sessioni per sistemi più complessi.

2) non effettuare il redirect ma realizzare un sistema che sia in grado di verificare se il POST è stato già eseguito, in modo da non ripeterlo se l'utente effettua un refresh della pagina. Questo sistema può utilizzare le sessioni, campi nascosti del form, ecc. Non è di immediata realzzazione se si vuole che l'utente non sia in grado di manomettere tale sistema. In questo caso la pagina che riceve il post può generare output.

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

mmm, e come si fa?

attualmente lavoro così:

link: gallery.php?action=addAlbum

[...]
include ("header.php");
[...]

case 'addAlbum':

      if($_POST) {
         $app-> insertAlbum($_POST, $_FILES);
      } else {
         $app-> addAlbum();
      }

      break;

[...]
include ("footer.php");
[...]

in $app->insertAlbum () c'è:

function insertAlbum ($dati, $file, $update = FALSE) {

       $nome = trim($dati['nome']);
       //print_r ($file);
       // Gestione del file da definire
       $folder = $file['folder']['name'];


       if(get_magic_quotes_gpc()) {
          $nome = stripslashes($nome);
       }

       $nome = mysql_real_escape_string($nome);

      $query = "INSERT INTO album (nome,folder)
               VALUES ('$nome', '$folder')";

      $msg = "Inserito";

      if(!$nome) {
         $messaggio = urlencode("Non hai inserito il nome");

                        // questo non va per i suddetti motivi, l'avevo preso dal corso
         header('location: gallery.php?action=done&msg='.$messaggio);
         exit;

      }

      if ($update) {
         $id = $dati['id'];
         $query = "UPDATE album SET
                  nome = '$nome',
                  folder = '$folder'
                  WHERE id = '$id'
                  ";
         $msg = "Aggiornato";
      }
      $result = mysql_query($query);

      if (!$result) {
         die("Errore nella query $query: " . mysql_error());
      } else {

                        // anche questo non va per le stesse ragioni
         $messaggio = urlencode("$msg l'album $nome e il folder $folder <br /> $query");
         header('location: '.$_SERVER['PHP_SELF'].'?action=done&msg='.$messaggio);
         exit;
      }

    }

come inserire un controllo? le sessioni mi sono sempre risultate ostiche e non immagino nemmeno come poterle usare.

questo caso è semplice, in linea di massima potrei anche fregarmene del refresh essendo io l'esecutore dello script, ma ovviamente non è così che dovrebbe essere...

risposto 9 anni fa
arjuna
X 0 X

Vuoi usare le sessioni per memorizzare un messaggio da mostrare nella pagina di destinazione del redirect? Perfetto, devi imparare ad usare le sessioni:

http://www.phpnews.it/articoli/php/le-sessioni/

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

[OT]

Ma che bella tag, non ci avevo ancora fatto caso

[/OT]

per quanto riguarda le sessioni: arghhhhhhhhhhhhhh!

deduco dalla tua risposta che è il metodo migliore per eseguire questa procedura.

adesso mi studio la pagina che hai linkato ma cmq, avendo gia intrapreso questo studio per l'autenticazione utente vorrei capire come usare le sessioni per questo fine...

risposto 9 anni fa
arjuna
X 0 X

Con le sessioni puoi memorizzare un messaggio in una variabile (che non verrà cancellata al termine dello script) e mostrarne il contenuto nella pagina richiamata dal redirect. Non dovrai così usare l'URL per passare il messaggio all'altra pagina.

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

fin qui è chiaro, e un'altra buona notizia è che le sessioni sono gia attive perchè come ti dicevo c'è la gestione dell'utente alla base del mio script quindi posso tranquillamente scrivere le mie variabili nell'array $_SESSION.

Ma cosa scrivere?

Come faccio a dire allo script che proprio quella query è gia stata eseguita?

risposto 9 anni fa
arjuna
X 0 X

Non devi usare le sessioni per evitare diripetere la query (cosa che non succederà perché dovrai fare un redirect!). Le sessioni ti possono servire per memorizzare informazioni che vuoi mostrare all'utente nella pagina di destinazione del redirect, tipo un messaggio "inserimento effettuato con successo"

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

ma come faccio a fare il redirect se l'output viene mandato prima ancora di eseguire lo script?

non posso usare header("Location:");

risposto 9 anni fa
arjuna
X 0 X

Quale output? Lo script non si limita a prendere i dati del POST e ad eseguire le query?

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

c'è un include ("header"); all'inizio che mi serve per gestire il layout del sito, per questo chiedevo se ob_start() potesse servire

risposto 9 anni fa
arjuna
X 0 X

Fai in modo che quell'include non venga eseguito se vuoi fare il redirect.

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

è proprio questo che non so come fare...

risposto 9 anni fa
arjuna
X 0 X
è proprio questo che non so come fare...

non puoi semplicemente cancellare l'istruzione?

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

ho risolto in un modo poco elegante:

if (!isset ($_GET['ctrl']) || ($_GET['ctrl'] != TRUE)) {
   include ("header.php");
}

in questo modo basta inserire nell'url la variabile ctrl per bypassare l'include...

risposto 9 anni fa
arjuna
X 0 X

Non puoi ferificare in qualche modo che si tratta di un POST (if(count($_POST))) ad un particolare script (if($_SERVER['REQUESTED_URI']))?

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

non ho capito

risposto 9 anni fa
arjuna
X 0 X

Volevo dire che il tuo controllo si basa sulla verificache di un dato passato via URL. Ovviamente questo dato potrebbe essere modificato da un utente smaliziato...

TI consigliavo quindi di cercare qualche altra soluzione, tenendo presente che non devi far apparire le intestazioni sono in un particolare caso: deve essere stato inviato un POST e lo script richiesto deve avere un nome preciso. In tutti gli altri casi puoi mostrare le intestazioni.

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

certo, questo lo avevo intuito infatti ho usato questo sistema solo perchè l'unico utente di questo script sono io e quindi non c'erano grossi problemi... però è per questo che ho chiesto, proprio perchè non è un modo corretto di agire

risposto 9 anni fa
arjuna
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda