viernes, 4 de enero de 2008

Session3 - PHP y MySQL parte I

Autor: hugo flores
hpfloresj@gmail.com

Hola que tal amigos de este curso, bueno escribo para darles algunas pautas sobre lo que aharemos mañana 05-01-2008, vamos a crear un mantenimiento (Leer, Actualizar, Borrar, Insertar) registros en una tabla, pero con clases en php.

Primero quisiera explicar algo, php trabaja con base de datos, pero no tiene un estandar para conectarme con distintas bases de datos, por ejemplo si trabajo con mysql la funcion para conectarme es mysql_connect, pero si trabajo con sql server me conecto mediante mssql_connect(), como veen existe un cambio en el nombre de los comandos, y esto sucede con todas las demas bases de datos, no hay un estandar que encapsule todo esto, por lo demas todo es sencillo.

Para los que quieren estudiar algo mas elaborado he creado un modulo de una aplicación llamada catalogo wbmusic que es un portal web de músicas, aqui les dejo para que lo estudien:
ejemplo

Requerimiento para esta clase:
  • Implementar una clase DBManager para MySQL: clase que me sirve para conectarme con la base de datos.
  • Implementar una clase RecordSet: clase que me permitirá recorrer una arreglo, que contiene los registros obtenidos de una consulta SQL en la base de datos.


1
<?
2
/********************************************/
3 /* Clase DBManager */
4 /*Clase que administra las conexiones con */
5 /*la base de datos. */
6 /*Autor: Hugo Flores Joseph 2006 */
7 /*Copyright (c) */
8 /********************************************/
9
require_once('Recordset.class.php');
10
11 class
DBManager{
12
13 private
$host='localhost';
14 private
$db ='wbmusic';
15 private
$user='';
16 private
$pass='';
17 private
$connectionID;// Retorna un enlace identificador de la conexion hecha con la base de datos
18
private $queryID = -1;// Esta variable guarda elúltimo resultado creado por link identifier de una consultra (almacena un entero<true=1,false=0>)
19
private $tempResultObj = '';// Almacena el resultado del Objeto Recientemente creado via el método execute()
20
private $error="";
21
22
23
//----------------Métodos Públicos--------------------//
24
25
public function DBManager($user='',$pass='')
26 {
27 if(!empty(
$user))$this->user=$user;
28 if(!empty(
$pass))$this->pass=$pass;
29
30 try{
31
$this->connectionID=@mysqli_connect($this->host,$this->user,$this->pass,$this->db);
32 if(!
$this->connectionID) throw new Exception(mysqli_connect_error());
33 }
34 catch(
Exception $e)
35 {
36 echo
"A ocurrido un error: ".$e->getMessage();
37 exit();
//termina la ejecucion del script
38
}
39 }
40
41
//funcion ADHOC utilizada con SELECT
42
public function executeQuery($sql = "")
43 {
44
$this->queryID = mysqli_query($this->connectionID,$sql);
45
$this->tempResultObj = new Recordset($this->queryID);//Inicializa un objeto sin considerar si la consulta retorna algun resultado o no.
46
return $this->tempResultObj;
47 }
48
//funcion ADHOC utilizada con INSERT, UPDATE, DELETE
49
public function executeUpdate($sql = "")//devuelve falso si la consulta tuvo exito
50
{
51
$resp=false;
52
$this->queryID = @mysqli_query($this->connectionID,$sql); //Inicializa un objeto sin considerar si la consulta retorna algun resultado o no.
53
if($this->queryID) $resp=true;
54 return
$resp;
55 }
56 public function
getConnection() { return $this->connectionID;}
57 public function
closeConnection(){ mysqli_close($this->connectionID);}
58 }
59
?>

Descripcion
  • Variables: las variables de esta clase se utilizan para almacenar los atributos del metodo mysqli_connect() que recibe como parametro el nombre del servidor mysql, el nombre de usuario de mysql, la clave correspondiente a ese usuario y por ultimo la base de datos.
  • Algunos otras variables que destacar:
  • $tempResultObj: variable que almacena un objeto de tipo Recordset que es el que contiene los registros de la consulta.
  • $connectionID: es un indentificador que me dice si he tenido exito al conectarme con la base de datos. su valor puede ser true/false
  • Con respecto a los métodos tenemos dos executeQuery y executeUpdate para ejecutar comandos SELECT y DELETE, UPDATE, INSERT respectivamente
y finalmente tenemos otra clase que utilizaresmos para las conexiones con mysql:


1
<?
2
/********************************************/
3 /* Clase Recordset */
4 /* clase que me permite manejar un conjunto */
5 /* de registros de una base de datos */
6 /* MySQL. */
7 /* Autor: Hugo Flores Joseph 2006 */
8 /* Copyright (c) */
9 /********************************************/
10
11
class Recordset{
12
//------Variables Públicas---------//
13
public $fields;
14 public
$BOF = null;// indica que la posición actual del registro esta antes del primer registrp en un Objeto Recordset.
15
public $EOF = null;// indica que la posición actual del registro esta después del último registro en un Objeto Recordset.
16
17 //------Variables Privadas---------//
18
private $_numOfRows = -1; // No Cambie este valor! SOLO LECTURA!
19
private $_numOfFields = -1; // No Cambie este valor! SOLO LECTURA!
20
private $_tempResult = '';// Almacena un valor que fue retornado desde una función específica de la Base de Datos
21
private $_queryID = -1;// Esta variable guarda el resultado de un link identifier
22
private $_currentRow = -1;// Esta variable guarda la actual fila en un Recordset.
23
24 //------Métodos--------------------//
25 // Devuelve: query id exitoso o falso si
26 // la función Constructor ha fallado
27
public function Recordset($queryID)
28 {
29
$this->_queryID = $queryID;
30 if (
$queryID) {
31
$this->_numOfRows = @mysqli_num_rows($this->_queryID);
32
$this->_numOfFields = @mysqli_num_fields($this->_queryID);//devuelve el número de campos de la consulta o result set
33
}
34 else {
35
$this->_numOfRows = 0;
36
$this->_numOfFields = 0;
37 }
38
// Si el resultado contiene filas
39
if ($this->_numOfRows > 0 && $this->_currentRow == -1) {
40
$this->_currentRow = 0;
41
$this->fields = mysqli_fetch_array($this->_queryID);//captura la fila en un array mssql_fetch_aaray(Devuelve: Un array que corresponde a la fila capturada, o FALSE si no hay más filas)
42
$this->EOF = false;
43
$this->BOF = false;
44 }
45 return
$this->_queryID;
46 }
//fin de método Recordset
47
48 // Devuelve: True si hay todavía filas disponibles, o False
49 // si no hay mas filas. Mueve a la proxima fila en un
50 // Objeto Recordset Especifico y hace que el registro de la fila actual
51 // y la correspondiente informaciónde la fila se recupere
52 // en la colección de los campos. Note: Al contrario del método moveRow(),
53 // cuando _currentRow esta getNumOfRows() - 1, EOF podria inmediatamente ser
54 // True. Si el número de fila no es proporcionado, la funcion podria posicionarse
55 //automáticamente en la primera fila.
56
public function nextRow()
57 {
58 if (
$this->getNumOfRows() > 0)
59 {
60
$this->fields = array();
61
$this->_currentRow++;
62
$this->fields = @mysqli_fetch_array($this->_queryID);
63
// Esto esta no trabajando. True todo el tiempo
64
if ($this->fields)
65 {
66
$this->_checkAndChangeEOF($this->_currentRow - 1);
67 return
true;
68 }
69 }
70
$this->EOF = true;
71 return
false;
72 }
//fin de método nextRow()
73
74 // Devuelve: true si es exitoso, false si ha fallado moveRow()
75 // moueve el puntero interno de una fila de el Objeto Recordset
76 // hacia un puntero de una fila especifico y la correspondiente
77 // información de la fila que podria recuperarse de la colección de
78 // campos. Si el número de fila no es proporcionado, la funcion podria posicionarse
79 // automáticamente en la primera fila.
80
public function moveRow($rowNumber = 0)
81 {
82 if (
$rowNumber == 0) {
83 return
$this->firstRow();
84 }
85 else if (
$rowNumber == ($this->getNumOfRows() - 1)) {
86 return
$this->lastRow();
87 }
88 if (
$this->getNumOfRows() > 0 && $rowNumber < $this->getNumOfRows()) {
89
$this->fields = null;
90
$this->_currentRow = $rowNumber;
91 if(@
mysqli_data_seek($this->_queryID, $this->_currentRow)) {//mueve el puntero interno de las filas Devuelve: TRUE si se ejecuta con éxito, FALSE si falla
92
$this->fields = @mysqli_fetch_array($this->_queryID);
93
/* This is not working. True all the time */
94
if ($this->fields) {
95
// No necesita llamar a _checkAndChangeEOF() por que
96 // la posibilidad de mover hacia la última fila ha
97 // sido manejada por el código de arriba
98
$this->EOF = false;
99 return
true;
100 }
101 }
102 }
103
$this->EOF = true;
104 return
false;
105 }
//fin de moveRow()
106
107 // Devuelve: true en caso de exito, false en caso de fallo de lastRow() moueve
108 // el puntero interno de la fila de un Objeto Recordset hacia la última fila
109 // y recupera la correspondiente información de la fila
110 // de la collecion de campos.
111
public function lastRow()
112 {
113 if (
$this->getNumOfRows() > 0) {
114
$this->fields = array();
115
$num_of_rows = $this->getNumOfRows();
116
$this->_tempResult = @mysqli_data_seek($this->_queryID, --$num_of_rows);//Devuelve: TRUE si se ejecuta con éxito, FALSE si falla y es --$num_of_rows por que en sql
117
if ($this->_tempResult) { //existe un ultimo registro en blanco entonces tengo que posicionarme en el
118 /* $num_of_rows decrementado anterioemente */ //penultimo registro.
119
$this->_currentRow = $num_of_rows;
120
$this->fields = @mysqli_fetch_array($this->_queryID);
121
/* Esto no esta trabajando. Verdadero todo el tiempo */
122
if ($this->fields) {
123
/* Caso Especial para hacer EOF=fallse. */
124
$this->EOF = false;
125 return
true;
126 }
127 }
128 }
129
$this->EOF = true;
130 return
false;
131 }
//fin de método lastRow()
132
133 // Devuelve: true en caso de éxito, false en caso de fallo, firstRow() mueve
134 // el puntero interno de la fila de un Objeto Recordset hacia la primera fila
135 // y recupera la correspondiente información de la fila
136 // de la collecion de campos.
137
138
public function firstRow()
139 {
140 if (
$this->getNumOfRows() > 0) {
141
$this->fields = array();
142
$this->_currentRow = 0;
143 if (@
mysqli_data_seek($this->_queryID, $this->_currentRow)) {
144
$this->fields = @mysqli_fetch_array($this->_queryID);
145
$this->EOF = false;
146
/* Esto no esta trabajando. Verdadero todo el tiempo */
147
if ($this->fields) {
148 return
true;
149 }
150 }
151 }
152
$this->EOF = true;
153 return
false;
154 }
155
156
157
// Retorna: El número de filas de un resultado.
158
public function getNumOfRows(){return $this->_numOfRows;}
159
160
/* Chequea y Cambia el Estado de EOF. */
161
public function _checkAndChangeEOF($currentRow)
162 {
163 if (
$currentRow >= ($this->_numOfRows - 1))
164 {
165
$this->EOF = true;
166 }else{
167
$this->EOF = false;
168 }
169 }
170
171
// close() solo necesita ser llamado si esta usando mucha memoria
172 // al correr su script. libera la memoria.
173
174
public function close()
175 {
176
$this->_tempResult = @mysqli_free_result($this->_queryID);
177 return
$this->_tempResult;
178 }
179 }
//fin de la clase
180
?>



Bien esta clase ya esta casi todo comentada y explicada, solo hay que aplicar los métodos, el que usaremos generalmente es el metodo nextRow() para avanzar un registro.

No hay comentarios: