Aggiornamento dei dati

L'aggiornamento dei dati presenti in una tabella MySQL è affidato ad una query di tipo UPDATE. Ad esempio, per modificare i dati associati al record con id = 5 della tabella "utenti" potremmo impiegare la seguente query:

UPDATE 
   utenti
SET
   nome = 'Mario',
   email = 'mario@email.it',
   sesso = 1,
   newsletter = 0,
   attivita = 2,
   messaggio = 'Ciao a tutti!'
WHERE
   id = 5

La semplice esecuzione della query in PHP richiede la realizzazione di un banale script:

<?php
// richiamo il file di configurazione
require 'config.php';

// richiamo lo script responsabile della connessione a MySQL
require 'connect.php';

// preparo la query di aggiornamento
$query = "UPDATE utenti SET
				nome = 'Mario',
				email = 'mario@email.it',
				sesso = 1,
				newsletter = 0,
				attivita = 2,
				messaggio = 'Ciao a tutti!'
				WHERE id = 5";

// invio la query
$result = mysql_query($query);

// controllo l'esito
if (!$result) {
	die("Errore nella query $query: " . mysql_error());
}

// chiudo la connessione a MySQL
mysql_close();

echo 'Query eseguita correttamente';
?>

Similmente a quanto visto nelle precedenti lezioni, anche l'aggiornamento dei dati all'interno di una reale applicazione web può richiedere ulteriori accorgimenti. Spesso infatti è necessario interagire con l'utente per determinare quale record aggiornare. Inoltre, se è l'utente a dover inserire i nuovi dati, è conveniente che possa farlo partendo da quelli attualmente presenti nel record. Un ipotetico script interattivo per la modifica dei dati della tabella "utenti" quindi dovrà prevedere le seguenti fasi:

  • mostrare un elenco dei record presenti nella tabella, associando a ciascuno un link che punta alla pagina di modifica dei relativi dati;
  • mostrare un form contenente i dati correntemente associati al record selezionato;
  • aggiornare i dati del record con quelli inviati dall'utente attraverso il form.

Vediamo il codice necessario a realizzare questo script:

<?php
// richiamo il file di configurazione
require 'config.php';

// richiamo lo script responsabile della connessione a MySQL
require 'connect.php';

if($_POST && isset($_GET['id']))
{
	aggiorna_record();
}
elseif(isset($_GET['id']))
{
	mostra_record();
}
else
	mostra_lista();

function mostra_lista()
{
	// mostro un eventuale messaggio
	if(isset($_GET['msg']))
		echo '<b>'.htmlentities($_GET['msg']).'</b><br /><br />';

	// preparo la query
	$query = "SELECT id,nome FROM utenti";

	// invio la query
	$result = mysql_query($query);

	// controllo l'esito
	if (!$result) {
		die("Errore nella query $query: " . mysql_error());
	}

	echo '
	<table border="1">
		<tr>
			<th>Nome</th>
			<th>&nbsp;</th>
		</tr>';

	while ($row = mysql_fetch_assoc($result))
	{
		$nome = htmlspecialchars($row['nome']);

		// preparo il link per la modifica dei dati del record
		$link = $_SERVER['PHP_SELF'] . '?id=' . $row['id'];

		echo "<tr>
				<td>$nome</td>
				<td><a href=\"$link\">modifica</a></td>
			</tr>";
	}

	echo '</table>';

	// libero la memoria di PHP occupata dai record estratti con la SELECT
	mysql_free_result($result);

	// chiudo la connessione a MySQL
	mysql_close();
}

function aggiorna_record()
{
	// recupero i campi di tipo "stringa"
	$nome      = trim($_POST['nome']);
	$email     = trim($_POST['email']);
	$messaggio = trim($_POST['messaggio']);

	// verifico se devo eliminare gli slash inseriti automaticamente da PHP
	if(get_magic_quotes_gpc())
	{
		$nome      = stripslashes($nome);
		$email     = stripslashes($email);
		$messaggio = stripslashes($messaggio);
	}

	// effettuo l'escape dei caratteri speciali per inserirli all'interno della query
	$nome      = mysql_real_escape_string($nome);
	$email     = mysql_real_escape_string($email);
	$messaggio = mysql_real_escape_string($messaggio);

	// recupero gli altri campi del form
	$sesso      = isset($_POST['sesso']) ? intval($_POST['sesso']) : 0;
	$newsletter = isset($_POST['newsletter']) ? 1 : 0;
	$attivita   = intval($_POST['attivita']);

	$id = intval($_GET['id']);

	// verifico la presenza dei campi obbligatori
	if(!$nome)
	{
		$messaggio = urlencode("Non hai inserito il nome");
		header("location: $_SERVER[PHP_SELF]?id=$id&msg=$messaggio");
		exit;
	}

	// preparo la query
	$query = "UPDATE utenti SET
				nome = '$nome',
				email = '$email',
				sesso = $sesso,
				newsletter = $newsletter,
				attivita = $attivita,
				messaggio = '$messaggio'
				WHERE id = $id";

	// invio la query
	$result = mysql_query($query);

	// controllo l'esito
	if (!$result) {
		die("Errore nella query $query: " . mysql_error());
	}

	// chiudo la connessione a MySQL
	mysql_close();

	$messaggio = urlencode('Aggiornamento effettuato con successo');
	header("location: $_SERVER[PHP_SELF]?msg=$messaggio");
}

function mostra_record()
{
	// mostro un eventuale messaggio
	if(isset($_GET['msg']))
		echo '<b>'.htmlentities($_GET['msg']).'</b><br /><br />';

	$id = intval($_GET['id']);

	// preparo la query
	$query = "SELECT nome,email,sesso,newsletter,attivita,messaggio FROM utenti WHERE id = $id";

	// invio la query
	$result = mysql_query($query);

	// controllo l'esito
	if (!$result) {
		die("Errore nella query $query: " . mysql_error());
	}

	// controllo che la SELECT abbia restituito un record
	// l'id passato via GET potrebbe essere stato manipolato
	if(mysql_num_rows($result) != 1) {
		die("l'ID passato via GET è errato");
	}

	list($nome,$email,$sesso,$newsletter,$attivita,$messaggio) = mysql_fetch_row($result);

	$nome      = htmlspecialchars($nome);
	$email     = htmlspecialchars($email);
	$messaggio = htmlspecialchars($messaggio);

	?>
	<form name="form_registrazione" method="post" action="">
	  <label>nome:
	  <input name="nome" type="text" value="<?echo $nome?>" />
	  </label>
	  <p>
	    <label>email:
	    <input name="email" type="text" value="<?echo $email?>" />
	    </label>
	  </p>
	  <p> Sesso:
	    <label>
	    <input type="radio" name="sesso" value="1" <?if($sesso==1) echo 'checked="checked"'?> />
	    M</label>
	    <label>
	    <input type="radio" name="sesso" value="2" <?if($sesso==2) echo 'checked="checked"'?>/>
	    F</label>
	  </p>
	  <p>
	    <label>inviami newletter:
	    <input name="newsletter" type="checkbox" value="1" <?if($newsletter) echo 'checked="checked"'?> />
	    </label>
	  </p>
	  <p>
	    <label>attivit&agrave;:
	    <select name="attivita">
	      <option value="0">:: seleziona ::</option>
	      <option value="1" <?if($attivita==1) echo 'selected="selected"'?>>studente</option>
	      <option value="2" <?if($attivita==2) echo 'selected="selected"'?>>lavoratore</option>
	      <option value="3" <?if($attivita==3) echo 'selected="selected"'?>>disoccupato</option>
	    </select>
	    </label>
	  </p>
	  <p>
	    <label>messaggio:<br />
	    <textarea name="messaggio" cols="40" rows="5"><?echo $messaggio?></textarea>
	    </label>
	  </p>
	  <p>
	    <input name="invia" type="submit" value="Invia" />
	  </p>
	</form>
	<?
}
?>

Analizziamo nel dettaglio il funzionamento dello script. Per prima cosa è necessario capire in quale fase della procedura di aggiornamento ci troviamo. Per farlo verifichiamo la presenza di dati inviati dall'utente ($_POST) e dell'id del record passato attraverso un link ($_GET['id']). Se non è presente nessuno di questi dati allora viene richiamata la funzione mostra_lista(). Se invece è presente solo l'id allora l'utente avrà cliccato su un link e quindi mostriamo il form per la modifica dei dati, attraverso la funzione mostra_record(). Se infine è presente sia l'id, sia i dati inviati col form allora procediamo all'aggiornamento del record, richiamando aggiorna_record(). Le righe 8-17 fungono quindi da "gestore degli eventi" del nostro script

La funzione mostra_lista() si occupa di estrarre e visualizzare l'elenco dei record presenti nella tabella "utente", associando a ciascuno di essi un link per l'aggiornamento dei dati (riga 48). Le righe 22-23 mostrano un eventuale messaggio generato da aggiorna_record(), funzione discussa in seguito. Si noti come i testi dinamici inseriti nella pagina vengono adeguatamente passati prima alla funzione htmlentities() per la conversione dei caratteri in entità HTML (righe 23,45).

La funzione mostra_record() recupera i dati associati al record da modificare, individuato da $_GET['id'], e li inserisce in un form. La funzione intval() applicata a $_GET['id'] ci assicura che l'id passato alla query è costituito da un numero intero (riga 131). Effettuata l'interrogazione al database viene verificata l'effettiva restituzione del record (riga 146) come controllo sulla validità dell'id. Anche in questo caso le stringhe dinamiche da inserire nel form ($nome, $email, $messaggio) vengono preventivamente passate alla funzione htmlentities() (righe 152-154).

La funzione aggiorna_record() ha infine il compito di effettuare la query di UPDATE con i nuovi dati inviati dall'utente. Eliminati i possibili spazi vuoti alle estremità delle stringhe $nome, $email e $messaggio con la funzione trim (righe 68-70), la funzione si occupa di effettuare un corretto escape delle stesse (righe 73-83). Come ampiamente discusso nella Lezione 5, dapprima si eliminano i backslash eventualmente inseriti da PHP e poi si procede ad effettuare l'escape con la funzione mysql_real_escape_string(). Viene verificato anche se l'utente ha inserito del testo nel campo "nome" considerato obbligatorio nell'esempio. In caso contrario viene ricaricata la pagina accodando all'URL un messaggio esplicativo (righe 93-97). Se invece il controllo ha esito positivo si procede con l'esecuzione della query di aggiornamento dati e si conclude lo script con un redirect del browser che riporta l'utente alla fase iniziale. Si noti ancora una volta l'uso fatto del redirect attraverso la funzione header() (righe 96, 122) come possibile soluzione al problema del refresh della pagina, già discusso nella Lezione 6.

Tutta la logica di funzionamento dello script si basa sull'id del record passato attraverso l'URL ($_GET['id']) pertanto il codice è potenzialmente affetto da un problema di sicurezza legato alla possibile alterazione di tale valore da parte dell'utente. Continuano a valere le considerazioni fatte a riguardo nella Lezione 8.

Prima di concludere è doveroso fare un breve riepilogo ed alcune precisazioni sull'uso della funzioni mysql_num_rows() e mysql_affected_rows() incontrate più volte nei precedenti esempi:

  • mysql_num_rows() restituisce il numero di record appartenenti ad un result set, prodotto ad esempio (ma non solo!) da una query di tipo SELECT;
  • mysql_num_rows() non funziona correttamente con mysql_unbuffered_query(), poiché restituirà il risultato corretto solo al termine della procedura di fetch;
  • mysql_affected_rows() restituisce il numero di record realmente interessato dall'ultima query di tipo INSERT, UPDATE o DELETE;
  • nelle versioni di MySQL precedenti alla 4.1.2, se viene effettuata una DELETE senza la clausola WHERE, mysql_affected_rows() restituisce sempre 0;
  • mysql_affected_rows() per una UPDATE non considera i record aggiornati con dati identici a quelli preesistenti. Solo i record realmente modificati vengono conteggiati. Tale comportamento può essere modificato passando il numero 2 come quinto parametro della mysql_connect(): mysql_connect("localhost", "user", "password", false, 2);
  • mysql_affected_rows() per una query di tipo REPLACE restituisce la somma dei record cancellati e di quelli inseriti;
  • se si è all'interno di una transazione non bisogna attendere la COMMIT per eseguire mysql_affected_rows() ma è necessario lanciarla subito dopo la query di INSERT, UPDATE o DELETE.

9 commenti

1 Alex Alex martedì 17 novembre 2009, ore 12:10
Ciao, lo script di questa pagina
http://www.phpnews.it/corsi/aggiornamento-dati/

restituisce un errore:

Parse error: syntax error, unexpected $end in C:\XAMPP\xampp\htdocs\test3\modifica.php on line 201
2 renadim martedì 4 ottobre 2011, ore 23:52
Hai risolto il problema? Come?
3 alykiss alykiss mercoledì 13 aprile 2011, ore 10:20
salve

sono finalmente arrivato alla fine del corso, inanzi tutto complimenti, chiaro, limpido come pochi.
uso wordpress quindi ho inserito i codici nelle pagine richiamandole una ad una in base a quello che voglio fare, ha funzionato tutto a meraviglia fino alla penultima la cancellazione dei dati, ho però un problema con la modifica.
Quando mi appare la tabella con i record da modificare clikkando su modifica non succede niente, ovvero mi indirizza all'index.php?id=2, che è la pagina iniziale del mio sito ed ovviamente non succede niente.
saresti così gentile da chiarirmi l'arcano?
In pratica quale pagina è linkata da modifica? ho provato a cambiarla ma niente da fare qualsiasi cosa ci metta non succede niente, pensavo che rimandasse alla stessa pagina del codice, ma niente da fare non funge :-)
grazie in anticipo e a presto
4 claudio_61 martedì 3 aprile 2012, ore 17:37
Scusate l'avevo postato su pagine precedenti a questa lezione:
Riscrivo il problema

1) Il passaggio dei dati funziona male, restituisce sul db tutti i valori a 1
2) come posso far arrivare direttamente al form l'utente loggato ?

Vi seguo con la massima attenzione da poco ma con entusiasmo.
Ciao
Claudio


<?php
// richiamo il file di configurazione
require 'config.php';

if (!isset($_SESSION['valid_user']))
if($_POST && isset($_GET['id']))
{
aggiorna_record();
}
else if(isset($_GET['id']))
{
mostra_record();
}
else
mostra_lista();

function mostra_lista()
{
// mostro un eventuale messaggio
if(isset($_GET['msg']))
echo '<b>'.htmlentities($_GET['msg']).'</b><br /><br />';

// preparo la query
$query = "SELECT id,nome FROM i_users";

// invio la query
$result = mysql_query($query);

// controllo l'esito
if (!$result) {
die("Errore nella query $query: " . mysql_error());
}

echo '
<table border="1">
<tr>
<th>Nome</th>
<th>&nbsp;</th>
</tr>';

while ($row = mysql_fetch_assoc($result))
{
$nome = htmlspecialchars($row['nome']);

// preparo il link per la modifica dei dati del record
$link = $_SERVER['PHP_SELF'] . '?id=' . $row['id'];

echo "<tr>
<td>$nome</td>
<td><a href=\"$link\">modifica</a></td>
</tr>";
}

echo '</table>';

// libero la memoria di PHP occupata dai record estratti con la SELECT
mysql_free_result($result);

// chiudo la connessione a MySQL
mysql_close();
}

function aggiorna_record()
{

$datains = trim($_POST['datains']);
$username = trim($_POST['username']);
$passwd = trim($_POST['passwd']);
$email = trim($_POST['email']);
$piva = trim($_POST['piva']);
$nome = trim($_POST['nome']);
$cognome = trim($_POST['cognome']);
$via = trim($_POST['via']);
$cap = trim($_POST['cap']);
$comune = trim($_POST['comune']);
$provincia = trim($_POST['provincia']);
$telefono = trim($_POST['tel']);
$id = isset($_GET['id']);

// preparo la query
$query = "UPDATE i_users SET
datains = '$datains',
username = '$username',
passwd = '$passwd',
email= '$email',
piva = '$piva',
nome = '$nome',
cognome = '$cognome',
via = '$via',
comune = '$comune',
provincia = '$provincia',
telefono = '$telefono'
WHERE id = $id ";
// invio la query
$result = mysql_query($query);
$result = mysql_query($query);

// controllo l'esito
if (!$result) {
die("Errore nella query $query: " . mysql_error());
}

// chiudo la connessione a MySQL
mysql_close();

$messaggio = urlencode('Aggiornamento effettuato con successo');
header("location: $_SERVER[PHP_SELF]?msg=$messaggio");
}


function mostra_record()
{
// mostro un eventuale messaggio
if(isset($_GET['msg']))
echo '<b>'.htmlentities($_GET['msg']).'</b><br /><br />';

$id = intval($_GET['id']);

// preparo la query
$query1 = "SELECT id,datains,username,passwd,email,piva,nome,cognome,via,cap,comune,provincia,telefono FROM i_users WHERE id = $id ";

// invio la query
$result1 = mysql_query($query1);

// controllo l'esito
if (!$result1) {
die("Errore nella query $query: " . mysql_error());
}

// controllo che la SELECT abbia restituito un record
// l'id passato via GET potrebbe essere stato manipolato
if(mysql_num_rows($result1) != 1) {
die("l'ID passato via GET è errato");


}

list($id,$datains,$username,$passwd,$email,$piva,$nome,$cognome,$via,$cap,$comune,$provincia,$telefono) = mysql_fetch_row($result1);



$datains = htmlspecialchars($datains);
$username = htmlspecialchars($username);
$passwd = htmlspecialchars($passwd);
$email = htmlspecialchars($email);
$piva = htmlspecialchars($piva);
$nome = htmlspecialchars($nome);
$cognome = htmlspecialchars($cognome);
$via = htmlspecialchars($via);
$cap = htmlspecialchars($cap);
$comune = htmlspecialchars($comune);
$provincia = htmlspecialchars($provincia);
$telefono = htmlspecialchars($telefono);


?>

<form name="form_registrazione" method="post" action="">

<br />Nome:<br />
<input type="text" name="nome" value="<?echo $nome?>">
<br />
Cognome:<br />
<input type="text" name="cognome" value="<?echo $cognome?>">
<br />
Via:<br />
<input type="text" name="via" value="<?echo $via?>">
<br />
Comune:<br />
<input type="text" name="comune" value="<?echo $comune?>">
<br />
CAP:<br />
<input type="text" name="cap" value="<?echo $cap?>">
<br />
Provincia:<br />
<input type="text" name="provincia" value="<?echo $provincia?>">
<br />
Recapito telefonico:<br />
<input type="text" name="tel" value="<?echo $telefono?>">
<br />
Username:<br />
<input type="text" name="username" value="<?echo $username?>">
<br />
Indirizzo e-mail:
<br />
<input type="text" name="email" value="<?echo $email?>">
<br />
Partita IVA<br />
<input name="piva" type="text" maxlength="11" />
<br />
<input name="datains" value="CURDATE()" />
<input name="id" value="<?echo $id?>" />
<input name="passwd" value="<?echo $passwd?>" />
<br />
<input type="submit" name="reg" value="Aggiorna">
</p>
</form>
<?
}
?>
5 sCrAuZz giovedì 10 maggio 2012, ore 21:49
Complimenti per questa lezione, ho trovato molte cose utili!! Grazie!
6 naruto1234 lunedì 12 novembre 2012, ore 16:46
Ottima guida ma mi chiedevo se qualcuno sa come inserire un form di ricerca anche per tirare fuori il nome da modificare, grazie
7 Gianni Tomasicchio lunedì 12 novembre 2012, ore 19:13
Dovresti partire dall'esempio presente della lezione "Selezione dei dati e recupero dei risultati - II".
In quello script la query di ricerca non ha filtri. Tu dovresti modificarla inserendo una condizione del tipo:
SELECT ... WHERE nome like '%$nome%'
dove $nome è la variabile che contiene il nome cercato dall'utente e proveniente dal form. Anche in questo caso $nome va protetto con mysql_real_escape_string
8 bilotti lunedì 25 marzo 2013, ore 19:26
Sto cominciando da poco ad usare PHP MySQL trovando questo corso chiaro. Mi sono arenato su Aggiornamento dei dati mi restituisce il seguente errore:
Parse error: syntax error, unexpected end of file in C:\EasyPHP-12.1\www\connessione\aggiorna.php on line 210
La linea 210 non esiste.
Grazie per l'aiuto
9 oberdorfer martedì 5 gennaio 2016, ore 17:38
Per evitare l'errore '... unexpected end of file ...' e' sufficiente convertire i tags di apertura del codice php:
<?
in:
<?php
dovunque compaiano.
Effettua l'accesso o registrati per inserire un commento