Edición con PHP de varios registros de la base de datos de una sola vez

  • Por
A veces nos facilita las cosas que se puedan editar a la vez varios registros de una base de datos. Vemos como recibir con un bucle todos los registros a editar y hacer el update.
En el manual básico de PHP ya se explicó como realizar una edición de los datos de una tabla de base de datos . En el ejemplo visto en ese artículo se podía seleccionar un registro, para editar sus datos. Pero imaginemos que necesitamos editar decenas o cientos de registros, entonces puede ser demasiado laborioso tener que editar los registros de uno en uno. En esos casos, tal vez nos interese hacer algo para que se puedan editar varios registros a la vez.

Lo que vamos a hacer es un sistema de edición que permita actualizar varios registros de la base de datos en una única acción, es decir, construir un formulario que muestre varios registros para editar, con un único botón de submit para enviar el formulario completo. La dificultad estriba en recibir del formulario todos los registros a editar y realizar el update para cada uno de ellos.

Tenemos una tabla de la base de datos con números de teléfono y nombres de contacto.
En este caso, para simplificar, vamos a editar los registros de 10 en 10. Tendremos que mostrar un formulario con los 10 primeros teléfonos y un enlace para ver los 10 siguientes, siempre que queden registros por mostrar en la base de datos.

Podemos ver el ejemplo en marcha para hacernos una idea exacta de nuestros objetivos.

En el script vamos a tener dos partes: una en la que se muestra el formulario y otra en la que se hacen los distintos update a partir de los datos recogidos. Toda la lógica la vamos a concentrar en una única página, donde, si no se reciben datos de formulario, se muestra el formulario. Si se han recibido datos de un formulario, entonces se deben actualizar los registros.

Mostrar el formulario

Lo primero que debemos de hacer es saber a partir de qué registro se debe mostrar el formulario. Porque podemos desear mostrar los primeros 10 valores o un conjunto de registros posterior.

if (isset($_GET["id_mostrar"]))
   $id_mostrar = $_GET["id_mostrar"];
else
   $id_mostrar = 0;


Con estas líneas vemos si recibimos por GET un identificador a partir del que mostrar los registros. Si no se recibe nada, se entiende que se desea recibir los registros desde el principio (id=0).

Para mostrar el formulario tenemos que recibir de la base de datos los registros a mostrar. Para ello se realiza una consulta de selección, limitando a 10 el número de registros a recibir.

$ssql="select * from manual_php where id>$id_mostrar limit 10";
$result=mysql_query($ssql);


Ahora, haremos un formulario para editar los teléfonos. Para cada registro, se mostrará una línea con el teléfono y el nombre de la persona. Cada línea tendrá unos campos de formulario, para el identificador del registro y para el número de teléfono. El campo donde se guarda el identificador lo haremos con un hidden y el teléfono con un campo de texto. Para nombrar los campos de formulario utilizaremos un numero, para que no sean siempre los mismos, porque si se llaman todos los campos igual, a la hora de recibirlos podemos tener problemas. El código que queremos generar tendrá una forma como esta:

<input type=hidden name='id1' value='1'>
Daniel
<input type=text name='telefono1' value='0147852'>

<input type=hidden name='id2' value='2'>
Claudio
<input type=text name='telefono2' value='9876654'>

...

<input type=hidden name='id10' value='88'>
María
<input type=text name='telefono10' value='000000'>


Vemos que el primer identificador tiene nombre "id1", el Segundo "id2" y así sucesivamente. Los números de teléfono también tienen campos con nombres distintos: "telefono1", "telefono2"... No vamos a dar opción a editar los nombres de contacto en este formulario, para simplificar las cosas.

Para generar el código del formulario utilizaremos un script PHP como el siguiente:

echo "<form action='edicion_a_la_vez.php' method=post>";
echo "\n<table align=center>";
echo "\n<tr><td><b>Nombre</b></td><td><b>Teléfono</b></td></tr>";

$i = 1;
while ($fila=mysql_fetch_array($result)){
   echo "\n<input type=hidden name='id$i' value='" . $fila["id"] . "'>";
   echo "<tr>";
   echo "<td>" . $fila["nombre"] . "</td>";
   echo "<td><input type=text name='telefono$i' value='" . $fila["telefono"] . "'></td>";
   echo "</tr>";
   $i++;
$ultimo_mostrado = $fila["id"];
}

echo "\n<tr><td colspan=2 align=center><input type='submit' value='Editar todos'></td></tr>";
echo "\n</table>";
echo "\n</form>";

Por último, mostraremos un enlace para ver los siguientes registros, si es que se han mostrado registros en esta página. Utilizamos la variable $ultimo_mostrado, para saber a partir de qué registro continuar.

if (isset($ultimo_mostrado))
   echo "\n<br><a href='edicion_a_la_vez.php?id_mostrar=" . $ultimo_mostrado . "'>Ver los 10 siguientes</a>";


Recibir los datos y hacer los UPDATE

Ahora vamos a mostrar la manera de recibir los datos del formulario y generar los update. Como tenemos hasta 10 registros por recibir, realizaremos un bucle FOR desde 1 hasta 10, con lo cual se podrán recibir todos los valores, concatenando el nombre del campo con el contador del for, desde 1 hasta 10.

Puede que en algunos casos no nos llegue el formulario con los 10 registros, porque haya menos para editar en el formulario, así que realizamos primero una comprobación para ver si están declaradas las variables que deberían llegar por POST. Por ejemplo, si está declarada la variable $_POST["id1"], quiere decir que estamos recibiendo datos también en $_POST["telefono1"].

for ($i=1;$i<=10;$i++){
   //para cada uno de los elementos que puede haber en el formulario
   if (isset($_POST["id" . $i])){
      //es que este registro estaba en el formulario
      $id = $_POST["id" . $i];
      $telefono = $_POST["telefono" . $i];
      $ssql = "update manual_php set telefono='$telefono' where id=$id";
      if (mysql_query($ssql))
         echo "<br>Teléfono actualizado con éxito";
      else
         echo "<br>Teléfono NO actualizado";
   }
}


En definitiva, se hace un bucle de 1 a 10 para recibir los datos que haya, si es que nos han llegado del formulario. Para cada registro que hemos detectado que nos llega por el formulario, se genera y ejecuta el update correspondiente, con lo que se irán actualizando los valores de la tabla.

El código completo

Mostramos el código completo de este ejemplo, para verlo de una manera global y asegurarnos que todo el mundo lo copia perfectamente:

<HTML>
<HEAD>
<TITLE>edicion_a_la_vez.php</TITLE>
</HEAD>
<BODY>
<h1 align="center">Edición de varios registros a la vez</h1>
<br>
<br>
<?
//Conexion con la base
require ($raiz . "../../../../librerias/principales.php");
$conn = mysql_conexion();

if (!$_POST){
   //si no recibo datos de POST, muestro el formulario

   //es posible que recibamos un id a partir del que hay que mostrar los datos
   if (isset($_GET["id_mostrar"]))
      $id_mostrar = $_GET["id_mostrar"];
   else
      $id_mostrar = 0;

   //extraemos de la base de datos los registros a mostrar
   //Ejecutamos la sentencia SQL, limitando la búsqueda a 10 registros
   $ssql="select * from manual_php where id>$id_mostrar limit 10";
   $result=mysql_query($ssql);

   echo "<form action='edicion_a_la_vez.php' method=post>";
   echo "\n<table align=center>";
   echo "\n<tr><td><b>Nombre</b></td><td><b>Teléfono</b></td></tr>";

   $i = 1;
   while ($fila=mysql_fetch_array($result)){
      echo "\n<input type=hidden name='id$i' value='" . $fila["id"] . "'>";
      echo "<tr>";
      echo "<td>" . $fila["nombre"] . "</td>";
      echo "<td><input type=text name='telefono$i' value='" . $fila["telefono"] . "'></td>";
      echo "</tr>";
      $i++;
      $ultimo_mostrado = $fila["id"];
   }

   echo "\n<tr><td colspan=2 align=center><input type='submit' value='Editar todos'></td></tr>";
   echo "\n</table>";
   echo "\n</form>";

   //si se han mostrado registros, pongo el enlace para ver los siguientes
   if (isset($ultimo_mostrado))
      echo "\n<br><a href='edicion_a_la_vez.php?id_mostrar=" . $ultimo_mostrado . "'>Ver los 10 siguientes</a>";
   }else{

   //es que he recibido datos de formulario, entonces tengo que recibirlos y actualizar la base de datos
   for ($i=1;$i<=10;$i++){
      //para cada uno de los elementos que puede haber en el formulario
      if (isset($_POST["id" . $i])){
         //es que este registro estaba en el formulario
         $id = $_POST["id" . $i];
         $telefono = $_POST["telefono" . $i];
         $ssql = "update manual_php set telefono='$telefono' where id=$id";
         if (mysql_query($ssql))
            echo "<br>Teléfono actualizado con éxito";
         else
            echo "<br>Teléfono NO actualizado";
      }
   }
      echo "\n<p><a href=edicion_a_la_vez.php>Volver</a>";
   }
?>
</BODY>
</HTML>

Para finalizar, podemos ver el ejemplo en marcha en una página aparte.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Piero Recchia

07/3/2006
El articulo esta bueno pero creo que tiene un detalle. En el bucle for deberia inicializar la variable $i con $id_mostrar ya que si lo haces con uno cuando se envie el grupo del 11 al 20 la condicion if (isset($_POST["id" . $i])) nunca va a ser cierta. Corrigeme se me equivoco.

RESPUESTA

No es necesario, el código está probado. Tenemos en el formulario una serie de input que tienen nombre desde id1 hasta id10, independientemente del value de esos input, que si corresponde con el identificador del registro que se está mostrando. Con lo cual, a la hora de recoger los valores, en el for, hay que recogerlos por su nombre desde id1 hasta id10.

Esto se ve más claro si echas un vistazo al código fuente del formulario generado por PHP.

<form action='edicion_a_la_vez.php' method=post>
<table align=center>
<tr><td><b>Nombre</b></td><td><b>Teléfono</b></td></tr>
<input type=hidden name='id1' value='13'><tr><td>Gerardo</td><td><input type=text name='telefono1' value='miamiguete'></td></tr>
<input type=hidden name='id2' value='3'><tr><td>Miguel Angel</td><td><input type=text name='telefono2' value='78787878787878'></td></tr>
<input type=hidden name='id3' value='14'><tr><td>Lopez</td><td><input type=text name='telefono3' value='7887854545'></td></tr>
<input type=hidden name='id4' value='6'><tr><td>Lo que sea</td><td><input type=text name='telefono4' value='qwqwq'></td></tr>
<input type=hidden name='id5' value='8'><tr><td>Ana</td><td><input type=text name='telefono5' value='227777851q5q55'></td></tr>
<input type=hidden name='id6' value='9'><tr><td>Pedro</td><td><input type=text name='telefono6' value='9832000000000000'></td></tr>
<input type=hidden name='id7' value='11'><tr><td>ping</td><td><input type=text name='telefono7' value='0033441100001144'></td></tr>
<tr><td colspan=2 align=center><input type='submit' value='Editar todos'></td></tr>
</table>
</form>

Piero Recchia

13/3/2006
Si tienes razon, de esa forma no lo habia visto, gracias por la aclaración.

puskasz

15/3/2006
como se podria hacer para que los campos que tienen datos no se puedan modificar y si estubieran vacios poder rellenarlos?

fermdp

08/7/2006
Parece que el ejemplo online no funciona!!! probare localmente en mi PC el ejemplo. Gracias !!!

gorgar

16/7/2006
hola, me gusta el script, pero me gustaria solamente para crear nuevos campos, no para editarlos, que modificaciones tendria que hacerle para que esl script solamente cerara nuevas tablas en la bd?
por si no se entiende bien:
tengo una base de datos llamada "base", dentro tiene una tabla que se llama "armas", esta tiene 20 campos, como por ejemplo, "modelo, calibre, marca, cantidad de rayas etc." lo que yo necesito es poder agregar mas armas, agregar modelos, calibres, marcas, cada uno con su propio id para poder leerlos desde mi pagina.

salu2 y gracias

Juan

30/8/2006
Hola les cuento que tengo una tabla llamada prueba solo con id, nombre, observacion y necesito recorrerla de a uno y dar siguiente si quiero seguir mirando los datos.

Ete ejemplo creo que me sirve si le coloco limit 1 pero no me funciona siendo que lo unico que le cambio es la tabla y los campos de estas

Si hay alguna otra manera con for u otra, se los agradezco.

Espero poder tener respuesta, desde ya gracias.

hckjr

02/9/2006
soy nuevo en esto
que ese archivo principal.php que me falta y donde esta

genio

21/9/2006
esta interesante el ejemplo si alquien quisiera ayudarme necesito un ejemplo de gestion de base de con todas las alternativas tipicas como insercion modificacion borrado actualizacion listado, inserccion de detalles etc etc si alguien puede ayudarme se lo agradecere a mister700 en hot ma il com

john

30/9/2006
require ($raiz . "../../../../librerias/principales.php");
que debo poner en esta parte no tengo niguna pagina principales.php

Angel de Venezuela

11/11/2006
a ustedes los foros que me han ayudado tanto hay tiene un script php para respaldar una base de datos MySQL con PHP me costo un mundo conseguirlo pero ahora lo comparto con ustedes:

<?php
$usuario="";
$passwd="";
$host="localhost";
$db="iutll";
$nombre="respaldo_".date("d-m-Y").".sql";
$drop=false;
$tablas=array("alumnos","usuarios","validacion","periodo");
$comresion=false;
$conexion=mysql_connect($host,$usuario,$passwd)or die("No se encontro el servidor:".mysql_error());
mysql_select_db($db,$conexion)or die ("No se encontro la base de datos:".mysql_error());
if(empty($tablas)){
$consulta="SHOW TABLES FROM $bd;";
$respuesta=mysql_query($consulta,$conexion)or die ("No se pudo ejecutar la consulta:".mysql_error());
while($fila=mysql_fetch_array($respuesta, MYSQL_NUM)){
$tablas[]=$filas[0];
}//fin del while
}//fin del if
/*-----se crea la cabecera del archivo-----*/
$info['dumpversion']="1.1b";
$info['fecha']=date("d-m-Y");
$info['hora']=date("h:m:s A");
$info['mysqlver']=mysql_get_server_info();
$info['phpver']=phpversion();
ob_start();
print_r($tablas);
$representacion=ob_get_contents();
ob_end_clean();
preg_match_all('/([d+]=>.*) /',$representacion,$matches);
$info['tablas'] = implode("; ",$matches[1]);
$dump="
#
+=====================================================================================
#| version: {$info['dumpversion']}
#| Generando el {$info['fecha']} a las {$info['hora']} por el usuario '$usuario'
#| servidor {$_SERVER['HTTP_HOST']}
#| MySQL version: {$info['mysqlver']}
#| PHP version: {$info['phpver']}
#| Bese de Datos: '$bd'
#| Tablas: alumnos,usuarios,validaciion,periodo
#|
# +====================================================================================
====";
foreach ($tablas as $tabla){
$drop_table_query="";
$create_table_query="";
$insert_into_query="";
if($drop){
$drop_table_query="DROP TABLE IF EXISTS `$tabla`;";
}else{
$drop_table_query="#No especificado";
}
$create_table_query="";
$consulta="SHOW CREATE TABLE $tabla;";
$respuesta=mysql_query($consulta,$conexion)or die ("No se pudo ejecutar la
consulta:".mysql_error());
while($fila=mysql_fetch_array($respuesta,MYSQL_NUM)){
$create_table_query=$fila[1].";";
}
$insert_into_query="";
$consulta="SELECT * FROM $tabla;";
$respuesta=mysql_query($consulta,$conexion)or die ("No se pudo ejecutar la
cosulta:".mysql_error());
while($fila=mysql_fetch_array($respuesta,MYSQL_ASSOC)){
$columnas=array_keys($fila);
foreach($columnas as $columna){
if(gettype($fila[$columna])=="NULL"){
$values[]="NULL";
}else{
$values[]="".$fila[$columna]."";
}
}//end del foreach
$insert_into_query.="INSERT INTO `$tabla` VALUES (".implode(",",$values)."); ";
unset($values);
}
$dump.="
#| Vaciado de la tabla'$tabla'
#|+---------------------------->
$drop_table_query

#|Estructura de la tabla '$tabla'
#+----------------------------->
$create_table_query

#|Carga de datos de la tabla '$tabla'
#+------------------------------>
$insert_into_query
";
}
// Envio
if(!headers_sent()){
header("Pragma: no-cache");
header("Expires:0");
header("Content-transfer-Encoding: binary");
switch($compresion){
case"gz":
header("Content-Disposition: attanchmet; filename=$nombre.gz");
header("Content-type: application/x-gzip");
echo gzencode($dump,9);
break;
case"bz2":
header("Content-Disposition: attachment; filename=$nombre.bz2");
header("Content-type: application/x-bzip2");
echo bzcompress($dump,9);
break;
default:
header("Content-Disposition: attachment; filename=$nombre");
header("Content-type: application/force-download");
echo $dump;
echo "";
}
}else{
echo "<b>ATENCION: probablemente ha ocurrido un error</b><br/> <pre> $dump </pre>";
}
?>

solo tienen que hacer las modificaciones pertinentes en cuanto a nombre de base de datos, servidor, contraseña etc

Samuel

09/5/2007
Sobre el srcipt funciona perfectamente pero si deseo filtrar registros, es decir, si no los deseo actualizar todos ahoriota sino solo algunos que tengan un campo comun (ejemplo: una fecha o un valor)como harias porque tu script no esta preparado para recibir el parametro url en la consulta

Naid

22/5/2007
No valdria bien una comprobacion de que el valor a actualizar no sea el mismo que estaba en la DB? Ya que con este metodo siempre actualizo todos los registros, aunque no los haya cambiado. Me imagino que con una nuevo Query podria obtener los datos y comprobarlos con un if si son iguales o no a los recibidos por post. Esto disminuiria la interaxion con la DB ya que si hay miles de registros, no seria muy eficiente. Pero igual esta muy bueno el articulo

ANDREA

24/7/2007
solo quiero decir gracias, llevaba mucho tiempo tratando de hacer esto.

Dios los bendiga...thanks

ivan

28/2/2008
Hola
He estado echando un vistazo al articulo que me ha venido muy bien, pero hay una cosa que no entiendo: ¿Como se sabe que filas se han modificado y cuales no? Porque cualquier cosa q tenga value se pasa al otro formulario via POST o GET no?
Gracias

mathvega

09/3/2009
Muchas gracias... a partir del código pude hacer el mantenedor de un sistema de materiales para los alumnos del liceo donde trabajo. Cada alumno tiene un codigo y los materiales llevan el codigo del alumno, un cod de material y a cantidad de c/u...

La idea es modificar todo las cantidades de un mismo alumno al mismo tiempo.

nnicanor

02/8/2012
consulta
como se podrá realizar un UPDATE con varias columnas, me explico; q aparte de modificar el telefono, me modifique otra columna, ejemplo CIUDAD??? saludos a todos

Aarón

02/11/2012
Gracias
Amigo gracias por el aporte, esta exelente!!

LHUIS

14/1/2013
NO SALE
Lo he tratado de hacer pero nada. Cuando cargo la página donde esta el ejemplo, y quiero ver el código fuente no me permite. A que se debe esto ...

elkin

23/8/2013
excelente
Muy buen aporte.

Gracias

Luiz Antonio Giachini

31/5/2014
Muito Bom
Gostei de mais o artigo, me ajudou pra caramba, tinha que editar um registro por vez, e agora da para editar dez ou mais por vez, e ainda tem paginação para os dez próximos.
Muito bom continuem assim.

Me gustó más el artículo, me ha ayudado mucho, tuve que editar un registro a la vez, y ahora la edición de diez o más a la vez, y aún así tener paginación para los próximos diez.
Muy bueno mantenerlo.

Albert

27/6/2016
Ver registros anteriores
Excelente. Articulo me sirvió de mucho.
Pero quisiera ver como puedo poner un link para ver los registros anteriores. En este caso se pone un botón para volver. pero te regresa en donde están los primeros registros. Espero puedan ayudarme.

Saludos

diego

14/7/2016
codigo
amigo me puede regalar el codigo completo de la actualizacion de datos