En la segunda entrega de esta serie, vamos a implementar métodos para la extracción y manipulación de datos. Comenzaremos con las funciones de acceso a datos, que serán las siguientes:
- getrow() nos devuelve un array con todos los campos de un registro determinado.
- getassoc() como getrow() pero los índices del array son una cadena con el nombre del campo.
- getarrayassoc() nos devuelve un array multidimensional que contiene un rango de registros, cada uno de los cuales con todos sus campos en un array asociativo.
<?php public function getrow( $row = 0, $query = 'main' ) { $return = false; for ($ct=0;$ct<$this->queries[$query]['numfields'];$ct++) { $return[$ct] = $this->get($row, $ct); } return $return; } public function getassoc( $row = 0, $query = 'main' ) { $return = false; for ($ct=0;$ct<$this->queries[$query]['numfields'];$ct++) { $return[$this->queries[$query]['fields'][$ct]['name']] = $this->get($row, $ct); } return $return; } public function getarrayassoc( $start = 0, $end = 0, $query = 'main' ) { $return = false; if ($end == 0) { $end = $this->queries[$query]['numrows']; } for ($ctr=$start;$ctr<=$end;$ctr++) { $return[$ctr] = $this->getassoc($ctr, $query); } return $return; } ?>
Con estas funciones ya tenemos solucionados nuestros requerimientos de acceso a datos, ahora vamos con las funciones que nos permitirán manipularlos:
- insert() nos facilitará la tarea de insertar nuevos datos en una tabla.
- Con update() podremos modificar registros.
- delete() será la función que utilizaremos para eliminar registros.
<?php public function insert( $table, $fields, $values = false, $query = 'main' ) { $return = false; if ($table !== false) { if (!$values) { $qry = 'INSERT INTO ' . $table . ' VALUES ( "' . implode( '", "', $fields ) . '" )'; } else { $qry = 'INSERT INTO ' . $table . ' ( "' . implode( '", "', $fields ) . '" )' . ' VALUES ( "' . implode( '", "', $values ) . '" )'; } $return = $this->query( $qry, $query ) } return $return; } public function update( $table, $fields, $values, $where = '1=1', $query = 'main' ) { $return = false; if ($table !== false) { $qry = 'UPDATE ' . $table . ' SET '; $tot = count( $fields ); for ($ct=0;$ct<$tot;$ct++) { if ($ct > 0) $qry .= ', '; $qry .= $fields[$ct] . '=' . '"' . $values[$ct] . '"'; } $qry .= ' ' . $where; $return = $this->query( $qry, $query ) } return $return; } public function delete( $table, $where = '1=1', $query = 'main' ) { $return = false; if ($table !== false) { $qry = 'DELETE FROM ' . $table . ' ' . $where; $return = $this->query( $qry, $query ); } return $return; } ?>
Gracias a estas funciones, nuestra clase comienza a ser operativa y ya podemos empezar a usarla en nuestros proyectos (de momento, sólo contra bases de datos MySQL; en las siguientes entregas, entre otras cosas, veremos lo sencillo que resulta añadir otros motores de bases de datos)
Hoy, para terminar, vamos a mostrar algún ejemplo de uso de nuestra nueva clase:
<?php require 'dblib.php'; # # Nos conectamos al servidor "host", con el usuario "usuario" y password "password" # y seleccionamos la base de datos "base_de_datos". El cuarto parámetro de la # cadena de conexión le dice a la clase que debe realizar la conexión con el servidor # en el momento de ser creada. # $db = new MyDBLayer( 'base_de_datos', 'host@usuario@password@true' ); # # Lanzamos un query sobre la base de datos y recibimos los datos en un array. # $db->query( 'SELECT * FROM coches' ); if ($db->queries['main']['numrows']) { $coches = $db->getarrayassoc(); } # # Generamos una tabla con los datos recogidos en el query. # $out = "<table>\n"; $out .= "\t<thead>\n"; $out .= "\t\t<tr>\n"; for ($ctf=0;$ctf<$db->queries['main']['numfields'];$ctf++) { $out .= "\t\t\t<th><{$db->queries['main']['fields'][$ctf]['name']}></th>\n"; } $out .= "\t\t</tr>\n"; $out .= "\t</thead>\n"; $out .= "\t<tbody>\n"; for ($ctr=0;$ctr<$db->queries['main']['numrows'];$ctr++) { $out .= "\t\t<tr>\n"; foreach ($coches[$ctr] as $key => $val) { $out .= "\t\t\t<td>$val</td>\n"; } $out .= "\t\t</tr>\n"; } $out .= "\t</tbody>\n"; $out .= "</table>\n"; echo $out; ?>
Este código podría servirnos para generar una tabla como la siguiente:
| <id> | <marca> | <modelo> | <color> |
|---|---|---|---|
| 1 | Ford | Mondeo | Negro |
| 2 | Renault | Megane | Rojo |
| 3 | Citroen | C4 | Gris |
Nos vemos en la siguiente entrega.
Escrito por grimborg el jue, 18 dic 2008
PDOStatement::fetch, fetchall ya hacen esto... ¿para qué reinventarlo? Te arriesgas a hacerlo peor, e.g. tu código permite SQL injection.
La abstracción debería ser algo que te permitiera hacer e.g. $coche = Coche::filter(array('color'=>'Gris', 'modelo'=>'C4')), en mi modesta opinión.
Escrito por Jose el lun, 29 dic 2008
Hola grimborg, es cierto que la clase PDOStatement ya hace todo esto y por supuesto, no pretendemos reinventar la rueda; estos humildes artículos sólo pretenden ser un ejercicio y servir de guía para programadores seguramente mucho menos expertos que tú...
En cuanto al SQL injection, en mi también modesta opinión, debería controlarse en las variables recibidas por $_GET y $_POST, no en la clase de abstracción de datos.
Y para terminar, el ejemplo que pones me parece estupendo y de hecho no supondría ningún problema incorporarlo al código del ejemplo ;)
Un saludo