Imprimir una tabla MySQL completa.

Resumen.

En este artículo vamos a presentar un código muy particular, que consiste en imprimir una tabla completa con solo introducir su nombre. No obstante, dado que si nuestras tablas tienen un volumen elevado, puede suponer un excesivo consumo de recursos que puede llegar a sobrepasar a nuestro servidor, la podremos configurar para que solo se muestren unos ciertos campos, un rango de registros, y por supuesto, un orden.

Artículo.

Hace tiempo, bastante tiempo, consultando un foro me encontré con que alguien buscaba un código que permitiera imprimir una tabla con simplemente enumerarla. Dado que yo trabajo en remoto con bastante frecuencia, me resulta un poco incomodo tener abierto phpMyAdmin para verificar que el trabajo que estoy haciendo evoluciona correctamente. Y por este motivo, me resulto interesante esa pregunta. Así que un día me puse manos a la obra con la pregunta en mente: ¿es posible hacer esto?

Y tras muchas vueltas, evolucionando paso a paso, me di cuenta que si, que era posible. Pero antes de entrar en materia considero importante mencionar unos detalles.

El primero, es que en términos generales este código no nos va a resultar útil a la hora de desarrollar un sitio Web. Los motivos, desvela mucha información, incluido los nombres de los campos de la tabla, y según el volumen de esta, puede resultar muy pesada su ejecución.

El segundo, es que está fundamentalmente orientado como ayuda al trabajo del programador, por lo que deberá estar muy alejado de miradas indiscretas.

El tercero, se le han añadido funciones para que, dado que el consumo de recursos puede ser muy elevado según el tamaño de la tabla, podamos limitar el número de registros, el rango de registros y el orden en que se muestran.

En cuarto y último lugar, hemos implementado un método para medir el consumo de recursos de este código. Para ello medimos los Kb consumidos antes de la ejecución del código, lo volvemos a medir tras la su ejecución, y la diferencia, es la memoria precisa para ser ejecutado. También hemos implementado dos métodos de recuento de resultados, uno mediante mysqli_num_rows, que aparece como comentario, y otro mediante COUNT. De esta forma podemos comprobar ese dicho según el cual la primera consume muchos mas recursos que la segunda. Hemos podido confirmar que efectivamente es así, con una tabla de 2913 registros de la cual solo hemos tomado 8 campos, y de los mas “ligeros”. Los resultados han sido:

Con mysqli_num_rows:
Antes: 453.58 Kb
Después: 614.1 Kb
Memoria usada: 160.52 Kb | 35.39%

Con COUNT:
Antes: 453.66 Kb
Después: 502.66 Kb
Memoria usada: 48.99 Kb | 10.8%

Como puede observarse, con COUNT el consumo de recursos es de solo el 10.8% del consumo inicial, mientras que con mysqli_num_rows es de el 35.39%. Los resultados son suficientemente contundentes, mas del triple. Por supuesto, mientras mas pequeña sea la tabla, menos diferencia habrá entre un recuento y otro.

De hecho, con la tabla propuesta y 9 registros los resultados han sido:

Con mysqli_num_rows:
Antes: 453.57 Kb
Después: 493.17 Kb
Memoria usada: 39.6 Kb | 8.73%

Con COUNT:
Antes: 453.48 Kb
Después: 492.96 Kb
Memoria usada: 39.48 Kb | 8.71%

Como podemos observar, con tablas de volumen tan reducido el consumo de recursos es prácticamente idéntico.

Con estas observaciones, vamos a explicar un poco el código.

Aunque el objetivo principal de este código es imprimir de manera rápida una tabla, dado que es un código que puede consumir considerables recursos de servidor, vamos a hacer una medición de la memoria consumida antes y después del código en cuestión mediante la función nativa memory_get_usage(). La variable $memoria_antes_kb recoge el consumo de recursos en kilobytes antes de iniciar la lectura de la tabla. La hacemos después de cargar la conexión a la base de datos por que todo acceso a base de datos requiere una conexión, por lo que, hacerlo antes solo podría infravalorar el consumo de recursos, ya que partiríamos de un consumo inicial mas elevado.

Seguidamente tenemos las 5 variables precisas para configurar el funcionamiento del script, que son:

$Ctabla.- Que recogerá el nombre de la tabla que queremos imprimir. Su valor no puede ser nulo.

$los_campos.- Esta variable puede tomar valor null, en cuyo caso imprimirá todos los campos de la tabla, o bien, si no queremos imprimir todos los campos de la tabla, tomará los valores de los campos que deseemos imprimir de la siguiente forma ' id,nombre,e-mail,f_reg…'.

$id_inicio.- Esta variable puede tomar el valor null en cuyo caso imprimirá todos los registros de la tabla. En caso que no deseemos imprimir todos los registros, por ejemplo por que la tabla es demasiado grande o simplemente solo sean de nuestro interés unos pocos registros, le indicaremos la posición del registro que nos interesa, que será un valor numérico entero positivo (INT) y único. En caso de tablas con id (campo imprescindible) autoincremental sin que haya sido eliminado ningún registro, coincidirá con el valor del id.

$mostrar_regis.- Si la variable $id_inicio tomó valor nulo null, esta también tomará valor nulo, e indicará el número de registros que queremos mostrar. Si tenemos tablas muy grandes es aconsejable marcar un cierto número de registros para que la ejecución del código sea fluida.

$orden.- Como su propio nombre indica, nos presentará los resultados en sentido de id ascendente o descendente, según indiquemos. Esta variable tomará los valores asc o desc, no puede tomar valor null.

Seguidamente tenemos un condicional que nos mostrará el número de registros en caso de no mostrarlos todos.

A continuación tenemos una función EliEspacios() que nos eliminará espacios en blanco si los hubiera en los campos que queremos imprimir.

Hacemos un recuento de los registros en nuestra tabla, donde tenemos dos códigos, uno como comentario, y otro activo. Lo hemos hecho así para poder comparar fácilmente la diferencia entre hacer el recuento con mysqli_num_rows() y COUNT(), solo es cuestión de dejar activo uno u otro y comparar los resultados de memoria consumida.

A continuación obtenemos el id de mayor valor y comprobamos si hay registros eliminados, en caso que existan, la variable $dif tomara el valor 0.

Mediante SHOW COLUMNS extraemos el nombre de los campos de la tabla, y si el array resultante $Nombres_Todos_Campos hay al menos 1 o mas elementos, es que la tabla existe, en cuyo caso procedemos a leer los datos contenidos en ella y los guardamos en una tabla que generamos mediante bucle FOR. Donde generamos una fila con los nombres de los campos para la parte superior e inferior de la tabla.

A continuación tenemos un condicional con la variable orden que contiene un bucle FOR. En cada parte de condicional lo que hacemos es cambiar el sentido de ejecución de bucle. En el caso de sentido ascendente el bucle se ejecuta como:
$k = $id_inicio; $k <= $id_fin; $k++
Y en caso de ser el orden descendente se ejecuta como:
$k = $id_fin; $k >= $id_inicio; $k--
Y todo lo demás es igual.

Por último presentamos un resumen de los resultados de la consulta e imprimimos la comparativa de recursos consumidos al ejecutar esta consulta, o más bien el conjunto de consultas que ejecuta el bucle, una por cada registro.
$_Datos_SQL = "SELECT * FROM $Ctabla WHERE id = '$k' LIMIT 1";
Sobre la tabla en la que presentamos los datos, le hemos puesto un campo checkbox para que podamos resaltar la fila que es de nuestro interés, ya que si tenemos muchos campos, nos puede costar identificar cada registro y cometer errores si no tenemos una marca diferenciadora.

Al mismo tiempo hemos creado un enlace a una página llamada “destino.php” (que no ha sido creada aún) que podría contener la totalidad de los registros mostrados en la tabla, lo que seria útil en el caso que no presentemos listados todos los campos que componen nuestra tabla.

Sin mas, el código completo es el siguiente:
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8" /> <title>Imprimir una tabla con solo dar su nombre.</title> <meta name="robots" content="index, follow" /> <script src="https://www.artesaniaweb.es/arch_dw/jquery-latest.js"></script> <style> table {border-color:#fff;} .selected {background-color:#C9FDB3;} </style> </head> <body> <?php // Imprimir una tabla MySQL // Codigo desarrollado por ArtesaniaWeb.ES /* Consulte la URL https://www.artesaniaweb.es/articulo.php?titulo=imprimir_una_tabla_mysql_completa-5f4l0 para obtener informacion sobre su configuracion y uso */ include('archivos/func_conexionBD.php'); $Conex_BD = ConectaBD(); // Medimos la memoria consumida antes de iniciar el codigo a medir $memoria_antes = memory_get_usage(); $memoria_antes_kb = round($memoria_antes / 1024, 2); // Variables a configurar $Ctabla = $tb1; // Nombre de la tabla que queremos imprimir <--configurable--> // La variable $los_campos recoge los campos que queremos mostrar, si es NULL, los muestra todos. $los_campos = null; // Ej: 'id, usuario, email, ip, f_regis' <--configurable--> // Si queremos que se muestren TODOS los resultados // $id_inicio y $mostrar_regis tomaran valor NULL // --------------- // Si queremos que se muestre PARTE de los resultados // $id_inicio y $mostrar_regis tomaran valor INT, entero y positivo $id_inicio = null; // Posicion del primer registro que se mostrará, no tiene que coincidir con el id <--configurable--> $mostrar_regis = null; // Numero de registros a mostrar <--configurable--> $orden = 'asc'; // asc o desc <--configurable--> // -------------------------------------------------------- // -------------------------------------------------------- if($mostrar_regis > 0){ $regis_parciales = "<p>Se muestran <b>$mostrar_regis</b> registros</p>"; }else{ $regis_parciales = null; } $id_fin = $id_inicio + $mostrar_regis - 1; function EliEspacios($canpos) { return preg_replace('/\s+/', '', $canpos); } $mostrar_campos = EliEspacios($los_campos); // Contamos mediante dos metodos para poder comparar el consumo de recursos de uno y otro // Los dos recuentos no deben estar activos al mismo tiempo // Recuento con MYSQLI_NUM_ROWS /* $_RegistrosTb = "SELECT id FROM $Ctabla"; $_Registros = mysqli_query($Conex_BD, $_RegistrosTb); $N_Registros = mysqli_num_rows($_Registros); */ // Recuento con COUNT $_RegistrosTb = "SELECT COUNT(id) AS Nregis FROM $Ctabla"; $_Cuenta_Reg = mysqli_query($Conex_BD, $_RegistrosTb); $T_regis = mysqli_fetch_assoc($_Cuenta_Reg); $N_Registros = $T_regis['Nregis']; // Extraemos el ID de mayor valor, debe ser numerico unico y autoincremental $_EXTRAE_Id = " SELECT id FROM $Ctabla ORDER BY id DESC LIMIT 1 "; $_EXTE_Id = mysqli_query($Conex_BD, $_EXTRAE_Id); $_Id = mysqli_fetch_row($_EXTE_Id); $idmax = $_Id[0]; $dif = $idmax - $N_Registros; // Extraemos los nombres de campo de la tabla $_Tabla = "SHOW COLUMNS FROM $Ctabla"; $Campos_Tabla = mysqli_query($Conex_BD, $_Tabla); while ($fila = mysqli_fetch_assoc($Campos_Tabla)){ $Nombres_Todos_Campos[] = $fila['Field']; } if(array_count_values($Nombres_Todos_Campos) > 0){ // La table existe, procedemos a su lectura if($mostrar_campos == null){ $Xcampos = array_values($Nombres_Todos_Campos); $nombres_campo = $Nombres_Todos_Campos; $N_Campos = count($nombres_campo); }else{ $Xcampos = explode(',', $mostrar_campos); $nombres_campo = $Xcampos; $N_Campos = count($Xcampos); } // Valores necesarios para crear la tabla HTML $encabezado = 1; $filas = $N_Registros; $columnas = $N_Campos; echo "<table border=\"1\" width=\"100%\" style=\"font-family: Verdana; font-size: 8pt\">\n"; //Iniciamos el bucle de las filas con los nombres de campo for($t=0; $t<$encabezado; $t++){ echo "<tr>\n <td bgcolor='#CCFFFF'></td>\n"; //Iniciamos el bucle de las columnas for($y=0;$y<$columnas;$y++){ echo "\t<td bgcolor='#CCFFFF'><b>".$nombres_campo[$y]."</b></td>\n"; } //Cerramos columna echo "</tr>\n"; } // Condicional para mostrar todos los registros o solo algunos if($id_inicio == NULL AND $mostrar_regis == NULL){ $id_inicio = 1; $id_fin = $filas+$dif; // Sumamos $dif para tener en cuenta los registros eliminados } if($orden == 'asc'){ //Iniciamos el bucle de las filas de los datos en sentido ascendente for($k = $id_inicio; $k <= $id_fin; $k++){ echo "<tr>\n <td align=\"center\"><input type=\"checkbox\"><br /><a href=\"destino.php?id=$k\" title=\"Ver registro\">rg</a></td>\n"; //Iniciamos el bucle de las columnas for($z = 0; $z < $columnas; $z++){ $_Datos_SQL = "SELECT * FROM $Ctabla WHERE id = '$k' LIMIT 1"; $_RESUL_Datos = mysqli_query($Conex_BD, $_Datos_SQL); $registro = mysqli_fetch_array($_RESUL_Datos); echo "\t<td>".$registro[$Xcampos[$z]]."</td>\n"; } //Cerramos columna echo "</tr>\n"; } }elseif($orden == 'desc'){ //Iniciamos el bucle de las filas de los datos en sentido descendente for($k = $id_fin; $k >= $id_inicio; $k--){ echo "<tr>\n <td align=\"center\"><input type=\"checkbox\"><br /><a href=\"destino.php?id=$k\" title=\"Ver registro\">rg</a></td>\n"; //Iniciamos el bucle de las columnas for($z = 0; $z < $columnas; $z++){ $_Datos_SQL = "SELECT * FROM $Ctabla WHERE id = '$k' LIMIT 1"; $_RESUL_Datos = mysqli_query($Conex_BD, $_Datos_SQL); $registro = mysqli_fetch_array($_RESUL_Datos); echo "\t<td>".$registro[$Xcampos[$z]]."</td>\n"; } //Cerramos columna echo "</tr>\n"; } } //Iniciamos el bucle de las filas con los nombres de campo for($t=0; $t<$encabezado; $t++){ echo "<tr>\n <td bgcolor='#CCFFFF'></td>\n"; //Iniciamos el bucle de las columnas for($y=0;$y<$columnas;$y++){ echo "\t<td bgcolor='#CCFFFF'><b>".$nombres_campo[$y]."</b></td>\n"; } //Cerramos columna echo "</tr>\n"; } echo '</table>'; DesconectaBD($Conex_BD); $fila_campos = implode(', ', $nombres_campo); // Imprimimops los resultados echo "<p>Tabla: <b>$Ctabla</b></p>\n $regis_parciales\n $N_Campos campos <br /> $N_Registros registros en total<br /> Registros eliminados: $dif <br /><br /> $fila_campos"; echo '<pre>'; print_r($nombres_campo); echo '</pre>'; // Realizamos una nueva medida de memoria consumida $memoria_despues = memory_get_usage(); $memoria_despues_kb = round($memoria_despues / 1024, 2); // Comparamos la memoria consumida antes de la ejecucion del codigo con la consumida despues echo "Antes: $memoria_antes_kb Kb <br /> Despues: $memoria_despues_kb Kb <br />"; $memoria_usada = $memoria_despues - $memoria_antes; $_memoria_antes = round($memoria_antes / 1024, 2); $_memoria_despues = round($memoria_despues / 1024, 2); $_memoria_usada = round($memoria_usada / 1024, 2); $porcentaje = round(($memoria_usada * 100) / $memoria_antes, 2); echo "Memoria usada: $_memoria_usada Kb | $porcentaje%"; }else{ // La tabla NO existe, lo informamos echo "<p>La tabla soliciticada <b>NO</b> existe</p>"; } ?> </body> <script> // Evento que se ejecuta cada vez que se pulsa sobre un checkbox de la tabla $("table input[type=checkbox]").on("click",function() { // añadimos o quitamos la clase selected al <tr> $(this).parents("tr").toggleClass("selected"); }); </script> </html>
Esperemos os haya gustado este artículo y encontréis alguna utilidad mas allá de la propuesta para este interesante código.
Tags: Imprimir || tabla || registros || bucle || memoria

Comentarios.

Sin comentarios, publica el tuyo.