Funcionalidad de la POO en php

Iniciado por . . ., 21 Enero 2010, 19:39 PM

0 Miembros y 2 Visitantes están viendo este tema.

. . .

Pues resulta que sigo con lo del POO. Espero que la gente experimentada en esto me pueda hechar una mano. La idea es hacer funcional la teoria sobre este paradigma:

Aqui vamos, tenemos una BD con una tabla llamada alumno, entonces siguiendo la teoria de POO debemos implementar un objeto para la representacion de esta tabla.

Tabla en Mysql

Código (sql) [Seleccionar]
CREATE TABLE `alumno` (
  `codigo` int(11) NOT NULL auto_increment,
  `nombres` varchar(30) NOT NULL,
  `apellidos` varchar(30) NOT NULL,
  `edad` int(11) NOT NULL,
  PRIMARY KEY  (`codigo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


Creamos una clase en php:

Código (php) [Seleccionar]
<?
class Alumno
{
private _codigo
private _nombre;
private _apellido;
private _edad;
}
?>


Bien ese es el comienzo .. supongamos que los posibilidades de trabajo para esta tabla puedan ser: un select, un insert, un update o un delete, cual seria la mejor forma de implementar los metodos antes mencionados ¡?

Gracias

. . .

#1
[Actualizado]
Si ven errores por favor comenten para corregirlos

Bueno pues aqui dejo un ejemplo 100% funcional de la funcionalidad del POO en php (valga la redundancia), creo que esto dara un ejemplo de lo potente que puede ser usar este paradigma.

Ire actualizando el hilo conforme mejore el codigo.

Saludos.

Conexion.php
Código (php) [Seleccionar]
<?
class Conexion
{
private $_CON; //conexion
private $_TABLA; //tabla a la que se le hara el select
private $_CODIGO; //codigo del registro de la tabla

function Conexion()
{
$this->_CON = mysql_connect('localhost','root','root');
mysql_select_db('web',$this->_CON);
}

function datos($tabla,$codigo)
{
$this->_TABLA = $tabla;
$this->_CODIGO = $codigo;
}

function select()
{
$this->Conexion();
$sql = "select * from $this->_TABLA where codigo='$this->_CODIGO'";
$res = mysql_query($sql,$this->_CON);
$datos = mysql_fetch_array($res);
mysql_close($this->_CON);
return $datos;
}
}
?>


Alumno.php
Código (php) [Seleccionar]
<?
include_once("conexion.php");

class Alumno extends Conexion
{
private $_ALUMNO; //array del alumno

function Alumno($codigo)
{
$this->datos(__CLASS__,$codigo);
$this->_ALUMNO = $this->select();
}

function _get_codigo()
{
return $this->_ALUMNO['codigo'];
}

function _get_nombres()
{
return $this->_ALUMNO['nombres'];
}

function _get_apellidos()
{
return $this->_ALUMNO['apellidos'];
}

function _get_edad()
{
return $this->_ALUMNO['edad'];
}
}
?>


index.php
Código (php) [Seleccionar]
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Documento sin título</title>
</head>
<body>

<?
include("alumno.php");
$alu = new Alumno(1);
echo $alu->_get_codigo()."<BR>";
echo $alu->_get_nombres()."<BR>";
echo $alu->_get_apellidos()."<BR>";
echo $alu->_get_edad();
?>

</body>
</html>


Saludos y en cuanto esto mejore les comento.
Gratz ¡¡¡

Nakp

por que no usas mysqli? es mucho mas facil que crear otra clase con un driver mas lento (mysqli es mas rápido :P)

http://php.net/manual/en/class.mysqli.php

podrias basar tu clase inicial en esta :P (no heredar, adaptar ;) )
Ojo por ojo, y el mundo acabará ciego.

. . .

Cita de: Nakp en 22 Enero 2010, 15:59 PM
por que no usas mysqli? es mucho mas facil que crear otra clase con un driver mas lento (mysqli es mas rápido :P)

¿ Un ejemplo funcional ?

Cita de: Nakp en 22 Enero 2010, 15:59 PM(no heredar, adaptar ;) )

Adaptar en que sentido .. un ejemplo por favor.

MazarD

Yo creo que no hay nada que mejorar, supongo que mapearás __CLASS__ en un xml o parecido y eres de los que prefieren sanear las variables en la entrada de datos, yo prefiero hacerlo en cada clase pero es cuestión de gustos, tampoco hay más.
Solo apuntar que la poo no implica encapsular el acceso a datos en clases,aunque es aconsejable. Esto en realidad es el patron de diseño active record.

Saludos.

-Learn as if you were to live forever, live as if you were to die tomorrow-

http://www.mazard.info
http://twitter.com/MazarD
irc://irc.freenode.org/elhacker.net

. . .

Cita de: MazarD en 22 Enero 2010, 18:09 PM
...eres de los que prefieren sanear las variables en la entrada de datos...

Cita de: MazarD en 22 Enero 2010, 18:09 PM
...Esto en realidad es el patron de diseño active record....

Podrias explicar ambos puntos por favor ¿?




Ahora con respecto al codigo: En la clase conexion yo he considerado la funcion select porque no solo se tendra la clase alumno sino tambien docente, personal, etc (todas ellas heredaran de conexion el metodo select) ... creen ustedes que el enfoque es el correcto ?

Tambien podria ser valido no considerar select dentro conexion, habia pensando en que la clase conexion tenga un metodo que retorne la variable $this->_CON ... de esa forma podria llamarse a ese metodo (desde las clases heredadas) y todas las consultas irian en cada clase (alumno, docente, personal, etc). Es decir:

Conexion.php
Código (php) [Seleccionar]
<?
class Conexion
{
private $_CON; //conexion

function Conexion()
{
$this->_CON = mysql_connect('localhost','root','root');
mysql_select_db('web',$this->_CON);
}

function conex()
{
$this->Conexion();
return $this->_CON;
}
}
?>


Alumno.php
Código (php) [Seleccionar]
<?
include_once("conexion.php");

class Alumno extends Conexion
{
private $_ALUMNO; //array del alumno

function Alumno($codigo)
{
$cone = $this->conex();
$sql = "select * from __CLASS__ where codigo='$codigo'";
                $consulta = mysql_query($sql,$cone);
$this->_ALUMNO = mysql_query($consulta);
}

function _get_codigo()
{
return $this->_ALUMNO['codigo'];
}

function _get_nombres()
{
return $this->_ALUMNO['nombres'];
}

function _get_apellidos()
{
return $this->_ALUMNO['apellidos'];
}

function _get_edad()
{
return $this->_ALUMNO['edad'];
}
}
?>


Supongo que tambien es valido, el unico inconveniente es que se generaria mas codigo, puesto que en el constructor iria lo mismo (en todas las clases: alumno, trabajador, docente, etc ..)

MazarD

#6
Citarentonces siguiendo la teoria de POO debemos implementar un objeto para la representacion de esta tabla.
El hecho de que implementes una clase para representar una tabla no es un paradigma, es un patrón de diseño que se llama active record. Si hicieras las consultas cuando las necesitases en una clase cualquiera seguiria siendo poo.

Citar...eres de los que prefieren sanear las variables en la entrada de datos...
Me refiero a que en:

Citar$sql = "select * from $this->_TABLA where codigo='$this->_CODIGO'";

Tienes una inyección sql, si es el usuario quien define codigo en el constructor y no la saneas en ese momento tienes un problema, yo prefiero sanear cada variable en cada clase porque tiendo a reutilizar mucho código, pero hay quien lo hace en $_REQUEST['codigo'] una sola vez, en el caso de que no venga del usuario no hay que preocuparse.

Pero bueno, supongo que no tiene importancia porque ahora con el segundo código veo que esto deber ser más un trabajo de clase que algo real.
Sea como sea lo que está claro es que los dos casos son correctos, pero mi punto de vista sobre el código:


Citar$sql = "select * from $this->_TABLA where codigo='$this->_CODIGO'";

Si creas una clase conexion, mejor que sea de verdad conexion y que la utilices siempre en esta clase o en cualquier otra(asbtracción) que sea plenamente objeto de base de datos simplemente heredando de la clase conexion.
El poner codigo= hace que esta clase solo te vaya a servir con tablas que tengan este campo.
Opciones:
-Lo mapeas en un xml igual que _TABLA
-No mapeas _TABLA, quitas el valor del constructor y creas selectById(tabla,campo,valor)

Imaginemos el segundo caso que es el más rapido de implementar, esto te permitiria tener una clase que te abstraeria de la base de datos, podrias crear metodos que te facilitarian mucho el trabajo a la larga: limpiartabla(tabla); deleteById(tabla,campo,valor); update(tabla,campo,valor,campocondicion,valorcondicion) etc etc

Entonces alumno evidentemente tiene que especificar más, en concreto la estructura de la tabla, con lo que tendrías selectbyId('Alumno','codigo',$codigo) donde codigo lo pasarias en el constructor. Además tambien seguirias especificando la estructura de la tabla con sus campos en cada getter y setter.
Que ventajas concretas te da esto gracias a la poo+active record:
-Si cambias de base de datos donde la sintaxi es distinta solo tendrás que crear otra clase conexion para la otra bd.
-Si cambias la estructura de la tabla usuario, ya sean los nombres de los campos, sus tipos o añades campos nuevos, solo tendrás que modificar la clase usuario.
Además del resto de ventajas de tener bien especificado cada concepto en una clase distinta.

El segundo código a mi me gusta menos, le quitas toda su potencia a conexion y el que después tengas que repetir código en el resto de clases no suele ser una buena señal.


Espero no haber sido muy coñazo, es que me gusta bastante la teoria de la poo :P.
Saludos!
-Learn as if you were to live forever, live as if you were to die tomorrow-

http://www.mazard.info
http://twitter.com/MazarD
irc://irc.freenode.org/elhacker.net