Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Mejora de objeto

Estas en el tema de Mejora de objeto en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola Estoy emprezando con los objetos y antes de cagarla (mucho) me gustaría que miraseis esta clase que estoy haciendo para ir corrigiendo desde el ...
  #1 (permalink)  
Antiguo 08/01/2005, 05:54
Avatar de Lord of freaks  
Fecha de Ingreso: octubre-2004
Ubicación: Madrid
Mensajes: 334
Antigüedad: 20 años, 2 meses
Puntos: 2
Mejora de objeto

Hola

Estoy emprezando con los objetos y antes de cagarla (mucho) me gustaría que miraseis esta clase que estoy haciendo para ir corrigiendo desde el principio los fallos por lo que os estaría infinitamente agradecido.

Código PHP:
class Usuario {

    var 
$id;
    var 
$nick;
    var 
$password;
    var 
$email;
    var 
$firma;
    var 
$puntos;
    var 
$admin;
    
    
// Constructor
    // Recoge los datos del usuario en cuestión
    
function Usuario($id){
    
    
// Almacena la id como atributo id
    
$this->id $id;
        
    
//recoge los datos del usuario de la bbdd y los almacena en los atributos
    
include("conex.php");
    
$result=mysql_query("select * from usuarios where Id_usuario='$this->id'");
    
$fila=mysql_fetch_array($result);
    
    
//libemaros la memoria y cerramos la conexión a la bbdd
    
mysql_free_result($result);
    
mysql_close($conexion);
    
    
//Almacenamos cada uno de los valores en los atributos del usuario
    
$this->nick=$fila[nick];
    
$this->password=$fila[password];
    
$this->email=$fila[email];
    
$this->firma=$fila[firma];
    
$this->puntos=$fila[puntos];
    
$this->admin=$fila[admin];
    
    
//imprimo los datos
    
echo '<pre>';
    
print_r($this);
    echo
'</pre>';
    }

Gracias de antemano y un saludo
__________________
Una vez un elemental de rayos mató una tribu entera de tritones.

¡¡ El sólo quería darse un baño !!

http://www.frikilandia.com

Neither Fu Nor Fa
  #2 (permalink)  
Antiguo 08/01/2005, 12:09
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 21 años, 2 meses
Puntos: 1
creo que vas muy bien. Solo recuerda que una clase es como una persona que se especializa unicamente en una cosa, en este caso, operaciones directamente relacionadas con un usuario en la base de datos, por ello no creo que sea conveniente que imprimas la información de ninguna forma. Solo guardala de tal forma que otra clase que sea la encargada de imprimir datos pueda leer el arreglo que devuelve tu clase e imprimirlo de la forma que corresponda, ya sea html, dhtml, texto simple, e incluso con una clase adecuada audio.


saludos
  #3 (permalink)  
Antiguo 08/01/2005, 15:34
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 21 años, 3 meses
Puntos: 41
Lo que yo pienso es que por más clase/objeto que utilizas, sigues programando estructurado. Ojo: no es lo mismo escribir clases que programar orientado a objetos (aunque es un primer paso).
Cuando creas una instancia de esa clase, automáticamente se ejecuta:
- Conexión a la base de datos mysql. (mysql_connect)
- Consulta por id de usuario. (mysql_query)
- Obtener los datos del usuario del resultset. (mysql_fetch)
- Guardar esos datos como atributos del objeto.
- Imprimir el objeto.

La idea de programar orientado a objetos es más o menos (ojo, que no domino para nada el tema, acabo de empezar) darle flexibilidad, extensibilidad, facilidad de mantenimiento a tus aplicaciones y reusabilidad a tus clases.

Por ejemplo:
Qué pasaría si mañana cambias tu aplicación a un servidor que no utiliza mysql sino postgreSQL u otro dbms?? Pues esta clase no te serviría para nada tal como está. y si además hay un sistema de noticias, otro de comentarios, otro de estadísticas, etc, etc... todos conectándose y haciendo directamente mysql_connect... pues ninguna de ellas te serviría y tendrías que reescribir prácticamente todas las clases de tu aplicación para que funcionen con postgreSQL.
La idea es que sólo tengas que cambiar una clase (o un pequeño grupo de ellas) que se encargan de interactuar con la base de datos. Esto sería una capa de abstracción de la BD. Entonces aquí en lugar de una sola clase usuario, tendrás otra(s) clase(s) que se encargará(n) de "mapear" el registro de la BD en un objeto. Además esas clases te servirán para todos los otros módulos de tu aplicación. Con lo que si cambias de dbms, sólo tendrás que cambiar esas clases sin tocar lo demás.
De la misma manera para imprimir los datos (como dice sism82). Si la clase los imprime en HTML directamente, es posible que luego tu aplicación crezca y ya no sólo necesites hacerlo en HTML, sino en XML, una versión para impresión, o simplemente más plantillas para la misma página, etc... Para eso tendrías que hacer otra clase igual que haga lo mismo (exactamente), pero que al final no los imprima en el mismo HTML sino de otra forma y así repetir toda la clase para cada plantilla de la misma página... o sea, no estarías reutilizando nada.

Como ya te dijo sism82, trat de que tu clase "Usuario" sea eso: un usuario con sus características (atributos) y sus acciones posibles (métodos)... deja la tarea de la conexión a la base de datos y la impresión del HTML a otras clases.

Saludos

Última edición por jpinedo; 12/01/2005 a las 14:45
  #4 (permalink)  
Antiguo 08/01/2005, 17:00
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 21 años, 3 meses
Puntos: 41
Por ejemplo:
Tu clase Usuario debería tener solamente sus atributos y accesores para esos atributos:
Código PHP:
class Usuario{
    var 
$id;
    var 
$nick;
    var 
$email;
    var 
$puntos;
    
    
/**
     * Constructor.
     * Recibe un array ($registro)  como el que se obtiene en mysql_fetch_array()
     */
    
function Usuario($registro){
        
$this->id $registro['id'];
        
$this->nick $registro['nick'];
        
$this->email $registro['email'];
        
$this->puntos $registro['puntos'];
    }
    
    
// Accesores
    // getters
    
function getID(){
        return 
$this->id;
    }
    function 
getNick(){
        return 
$this->nick;
    }
    
//etc, etc con los demás atributos
    
    // setters
    
function setID($nuevoID){
        
$this->id $nuevoID;
    }
    function 
setNick($nuevoNick){
        
$this->nick $nuevoNick;
    }
    
// etc, etc... con los demás atributos.

Y podrías hacer una clase BaseDeDatos que sea la que se comunica con la BD:
Código PHP:
class BaseDeDatos{
    
// id de conexión
    
var $_con;
    
    
// Constructor. Establece la conexión.
    
function BaseDeDatos($servidor,$usuario,$password,$nombre_bd){
        
$this->_con mysql_connect($servidor,$usuario,$password);
        
mysql_select_db($nombre_bd,$this->_con);
    }
    
    
// query(): realiza la consulta
    
function query($sql){
        return @
mysql_query($sql,$this->_con);
    }
    
    
// fetch_array(): Devuelve un registro en un array asociativo
    
function fetch_array($res){
        if (
$fila mysql_fetch_array($res)){
            return 
$fila;
        }else{
            return 
false;
        }
    }

Y entonces ya no tendrías que mencionar a "mysql" por ningún otro lado.

Podrías utilizar estas dos clases así:
Código PHP:
include('class.baseDeDatos.php');
include(
'class.usuario.php');
$bd = &new BaseDeDatos("localhost","usuario","xxxxx","mi_base");
$result $bd->query("SELECT id,nick,email,puntos FROM usuarios where id='$id'");
$fila $bd->fetch_array($result);

$user = &new Usuario($fila);

echo 
'<pre>';
print_r($user);
echo
'</pre>'
Como ves, la clase Usuario representa sólo un usuario y la clase BaseDeDatos las conexiones y funciones que permiten interactuar con una BD... El resto del manejo se hace fuera de ellas.

Ahora, podrías tener otra clase que se encargue de manejar los usuarios. En este caso sólo obtienes un usuario por su id. Pero sería mejor tener una clase que pueda manejar también otras consultas y crear instancias de usuarios, por ejemplo para agregar un nuevo usuario a la BD, o editar alguno existente, o eliminar... etc.
También podrías tener otra clase que se encargue de imprimir lo que quieras. Pero no dentro del usuario. (O en último caso, por un tema de pruebas podrías poner dentro del usuario una función "mostrar()" o "imprimir()" que imprima el contenido del objeto, pero de ninguna manera en el constructor).

No he pretendido para nada darte una solución "correcta" ni mucho menos... porque las clases son ultra básicas y sólo pretenden explicar... además, como dije, yo estoy en plena búsqueda de estos temas... así que cualquier opinión/correción será bienvenida.

Saludos

Última edición por jpinedo; 08/01/2005 a las 17:25
  #5 (permalink)  
Antiguo 08/01/2005, 19:04
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 21 años, 3 meses
Puntos: 41
Algo adicional:
Yo puse accesores para leer y escribir en métodos separados (get**() y set**()). Existen formas alternativas para los accesores y métodos en general como explica Webstudio en este post:
http://www.forosdelweb.com/showpost....6&postcount=23

Saludos

Última edición por jpinedo; 08/01/2005 a las 19:14
  #6 (permalink)  
Antiguo 07/02/2005, 17:57
 
Fecha de Ingreso: febrero-2005
Mensajes: 28
Antigüedad: 19 años, 10 meses
Puntos: 1
Respecto a la propuesta de jpinedo,
¿por que no poner las propiedades públicas directas?
Public $id;
Public $nick;
y despues un método Update que actualice la base de datos a partir de las propiedades píblicas.

Otro tema por la expriencia que tengo, un objeto lo vamos a necesitar inicizalizar de 2 maneras, con el código de forma directa o conm e lrecordset cuandop estamos construyendo una clase, ¿que tal este construct y select?:
function __construct($CodigoPelicula = 0)
{
$NumeroParametros = func_num_args();
/* Si hay parametros es que se está construyendo la clase
poniendo el código en la sentencia new */
if ($NumeroParametros >0)
{
$this->Select($CodigoPelicula);
}
}

function Select($CodigoPelicula)
{
// Determinar el tipo de Variable que se recibe
/*Control 1º: Se pasa un recordset porque externamente se
está creando una colección */
/* Control 2ª: Se pasa como valor el codigo del registro
y se debe acceder en ufnción del mismo */
if (is_numeric($CodigoPelicula) )
{
// Tratamiento de Acceso para números
$sql = "Select * From Elementos ";
$sql.= "Where ElementoID=".$CodigoPelicula;
}
elseif (is_string($CodigoPelicula))
{
// Tratamiento de Acceso para String
$sql = "Select * From Elementos ";
$sql.= "Where ElementoID='".$CodigoPelicula."'";
}
else
{
{
$this->RellenarPropiedades($CodigoPelicula);
return; // Se sale de la función
}
}
// Crear objeto Database
$db = new AuxDB();
$db->conectar();
/* Sentencia Select para leer el registro en la tabla
elementos correspondiente a una película determinada */
$rst = $db->ejecutarSQL($sql);
// Desconexión con el servidor de bases de datos
$db->desconectar();
// Obtener la fila de datos
$reg =$db->siguienteFila($rst);
$this->RellenarPropiedades($reg);
}
private function RellenarPropiedades($Registro) {
// Se rellenan las propiedades de esta clase
$this->AñoEstreno = $Registro['AñoEstreno'];
$this->GeneroCinematograficoID = $Registro['generocinematograficoid'];
}
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:12.