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

Mi primer intento de clase

Estas en el tema de Mi primer intento de clase en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Este es mi primer acercamiento serio con POO. Basandome en algunos ejemplos hice una clase para ejecutar consultas a una DB MySQL. Código PHP: <? ...
  #1 (permalink)  
Antiguo 26/06/2007, 13:04
 
Fecha de Ingreso: octubre-2003
Mensajes: 540
Antigüedad: 20 años, 6 meses
Puntos: 1
Mi primer intento de clase

Este es mi primer acercamiento serio con POO.
Basandome en algunos ejemplos hice una clase para ejecutar consultas a una DB MySQL.


Código PHP:
<?

class Mysql {

    var 
$db_host;
    var 
$db_user;
    var 
$db_pass;
    var 
$db_name;
    
    var 
$conn_id 0;
    var 
$query_id 0;
    
    var 
$errno 0;
    var 
$error "";
    
        
    function 
Mysql ($host=""$user=""$pass=""$name="") {
    
        
$this->db_host $host;
        
$this->db_user $user;
        
$this->db_pass $pass;    
        
$this->db_name $name;
                
    }    
    
    
    
    function 
connect ($host$user$pass$name) {
    
        if (
$host != ""$this->db_host $host;
        if (
$user != ""$this->db_user $user;        
        if (
$pass != ""$this->db_pass $pass;
        if (
$name != ""$this->db_name $name;
    
        
$this->conn_id mysql_connect($this->db_host$this->db_user$this->db_pass);
        
        if (!
$this->conn_id) {

            
$this->error "cant connect to db server";
        
            return 
0;
        
        }

        if (!@
mysql_select_db($this->db_name$this->conn_id)) {

            
$this->error "Can't connect to ".$this->db_name ;

            return 
0;

        }
        
        return 
$this->conn_id;
        
    }
    
    
    function 
query ($sql="") {
    
        if (
$sql == "") {

            
$this->error "Invalid SQL Query";
            
            return 
0;
        
        }

        
$this->query_id = @mysql_query($sql$this->conn_id);
        
        if (!
$this->query_id) {

            
$this->errno mysql_errno();            
            
$this->error mysql_error();
        
        }
        
        return 
$this->query_id;

    }
    
}
La duda puntual es esta.....yo hasta acá me conecto y ejecuto una consulta, pero no veo como construir un método para manipular los datos.
Hasta ahora lo hago de esta forma:

Código PHP:
<?php

require ("mysql.class.php");

$my_query = new Mysql;

$my_query->connect("localhost""user""pass""mydb");

$rows $my_query->query("SELECT * FROM table");

while (
$row mysql_fetch_array($rows)) {

    echo 
$row["foo"]."<br>\n";

}

?>

No sé, estoy bastante liado, pero me da la sensación de que en este último paso estoy volviendo a programar estructuradamente. De que forma lo harían uds?
Espero que se entienda mas o menos lo que quiero decir, cualquier ayuda es bienvenida.
  #2 (permalink)  
Antiguo 26/06/2007, 15:09
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Mi primer intento de clase

Esta bien tu clase pero si la bajas a nivel estructural, lo mejor es que tu metodo query te regrese otro objeto que englobe al resultado y sobre el que puedas hacer algo asi:
Código PHP:
while( $row $rows->fetchRow() ) {


Saludos.
  #3 (permalink)  
Antiguo 26/06/2007, 15:47
 
Fecha de Ingreso: octubre-2003
Mensajes: 540
Antigüedad: 20 años, 6 meses
Puntos: 1
Re: Mi primer intento de clase

Gracias por la aclaración, si alguien puede postear algun ejemplo mejor todavía.
  #4 (permalink)  
Antiguo 26/06/2007, 16:18
 
Fecha de Ingreso: junio-2005
Mensajes: 981
Antigüedad: 18 años, 10 meses
Puntos: 2
Re: Mi primer intento de clase

Cita:
Iniciado por Finseneu Ver Mensaje
Gracias por la aclaración, si alguien puede postear algun ejemplo mejor todavía.
El tema es el siguiente, no es muy dificil hacer un "contenedor" para devolver el resultado, pero como no hay muchas formas de hacerlo si se te muestra un ejemplo se te hace la tarea .

Te explico un poquito, la clase "contenedor-de-resultado" debería trabajar igual que un array, con un método para "siguiente" y "previo" registro y éste no debe guardar los resultados como te los devuelve "mysql_query()" porque el día que cambies de motor deberas tocar las dos clases y no es la idea. Se me ocurre crear el objeto, iterar los resultados dentro de la clase MySql e ir guardandolos en el contenedor y una vez que se termina de iterar se devuelve el objeto.

Creo que ya te di una idea, verdad? Tratá de realizarla y nos muestras y en todo caso cuando ya tengas algo hecho se discute de como mejorar

Saludos.
  #5 (permalink)  
Antiguo 26/06/2007, 19:42
 
Fecha de Ingreso: octubre-2003
Mensajes: 540
Antigüedad: 20 años, 6 meses
Puntos: 1
Re: Mi primer intento de clase

Le agregue métodos nuevos....

Código PHP:

    
function numRows() {

        if(
$this->query_id==0) { die($this->error); }
        return 
mysql_num_rows($this->query_id);

    }
    
    
    
    function 
numFields() {

        if(
$this->query_id==0) { die($this->error); }
        return 
mysql_num_fields($this->query_id);

    }


    
 
    
    function 
getFieldValue($field) { 
    
        
$this->field $field;
        
        while (
$this->row mysql_fetch_row($this->query_id)) {
        
            for(
$i=0;$i $this->numFields();$i++) {
            
                if(
mysql_field_name($this->query_id$i) == $this->field) {
                
                    
$this->field_value[] = $this->row[$i];
                
                }
            
            }
        
        }
    
        return (
$this->field_value);
    
    } 

pero no se, creo que sigo en lo mismo por la forma en que lo tengo que implementar....

Código PHP:

<?php

require ("mysql.class.php");

$my_query = new Mysql;

$my_query->connect("localhost""user""pass""mydb");

$rows $my_query->query("SELECT * FROM table");

foreach (
$my_query->getFieldValue("mail") as $field) {

echo 
$field."<br>\n";
}

?>
  #6 (permalink)  
Antiguo 26/06/2007, 21:56
 
Fecha de Ingreso: junio-2005
Mensajes: 981
Antigüedad: 18 años, 10 meses
Puntos: 2
Re: Mi primer intento de clase

A los efectos practicos esta bien pero no has hecho una clase nueva . Te explico algunas cosas que me parecen. Primero que nada trata de no depender del motor, con esto quiero decir es que cuando ejecutes la query iteres entre los resultados y los guardes en un contenedor de cualquier tipo (un array o un objeto preferentemente ). Para saber cuantos números de registro devolvio simplemente alcanza con contar los elementos del array (con count() ) y no dependemos del motor usando xxx_num_rows(). Otro problema que tenes con tu clase es que cuando hagas una segunda conculta perdes los resultados de la primera por eso esta bueno separar donde se hacen las query's y donde guardas los resultados.

Trata de implementar algo y seguimos tratando.

Saludos.
  #7 (permalink)  
Antiguo 27/06/2007, 08:08
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Mi primer intento de clase

Difiero un poco de tu idea DarioDario es mejor en este caso usar diferentes motores y no descargar todos los resultados si no mas bien que la clase DB sea una Factory y ya tener diferentes motores implementados igual con sus resultados, asi cada método Query te regresa un objeto del tipo Result donde ya independientemente del motor que la inicio te regresa los resultados, todo atado a una interfase para que sea igual la forma de ciclar por los resultados.

Saludos.
  #8 (permalink)  
Antiguo 27/06/2007, 08:55
 
Fecha de Ingreso: junio-2005
Mensajes: 981
Antigüedad: 18 años, 10 meses
Puntos: 2
Re: Mi primer intento de clase

Cita:
Iniciado por GatorV Ver Mensaje
Difiero un poco de tu idea DarioDario es mejor en este caso usar diferentes motores y no descargar todos los resultados si no mas bien que la clase DB sea una Factory y ya tener diferentes motores implementados igual con sus resultados, asi cada método Query te regresa un objeto del tipo Result donde ya independientemente del motor que la inicio te regresa los resultados, todo atado a una interfase para que sea igual la forma de ciclar por los resultados.

Saludos.
Yo concuerdo totalmente con vos y sería lo que yo recomendaría y haría pero... como este era su "primer acercamiento serio" no quería agobiarlo con tantos conceptos nuevos de una sola vez. Dándole esas explicación -que es buena y es lo que debería hacerse- el se tendría que preocupar por entender que es un Factory y volver a desarrollar las clases sin terminar de englobar una idea clara con este ejemplo simple.

Yo pienso que debería ser una clase Factory, N-clases que serían los distintos motores y una clase que sería la que encapsule los resultados no importa de que motor (tal como lo dices). Pero creo que el camino sería demasiado empiedrado para llevarlo ya por ahí.

Ahora re-leyendo veo que dices que este todo atado a una interface, pero te refieres a las distintas implementaciones de los motores? Porque no lo veo lógico que hagamos la interface para la clase Result ya que esta no debería cambiar según el motor porque debería ser capaz se ser independiente. Me estoy equivocando en algo?

Saludos.
  #9 (permalink)  
Antiguo 27/06/2007, 09:11
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Mi primer intento de clase

La idea de que todo este atado a la misma interface es para que cada motor que regrese un resultado tenga la misma firma de metodos, es decir atar todo a un mismo contrato y que sepas que independientemente si estas usando mysql, oracle, o postgre, puedes usar $result = $db->Query() o $result->fetchRow() ya que todos los metodos usan la misma interface que los obliga a implementar esos metodos.

Saludos.
  #10 (permalink)  
Antiguo 27/06/2007, 09:56
 
Fecha de Ingreso: junio-2005
Mensajes: 981
Antigüedad: 18 años, 10 meses
Puntos: 2
Re: Mi primer intento de clase

Cita:
Iniciado por GatorV Ver Mensaje
La idea de que todo este atado a la misma interface es para que cada motor que regrese un resultado tenga la misma firma de metodos, es decir atar todo a un mismo contrato y que sepas que independientemente si estas usando mysql, oracle, o postgre, puedes usar $result = $db->Query() o $result->fetchRow() ya que todos los metodos usan la misma interface que los obliga a implementar esos metodos.

Saludos.
Si, la teoría de la interface la tengo mas o menos clara. Yo lo que no entiendo es porque aplicarla en este ejemplo, la clase Result puede ser una y genérica para cualquier motor. Ejemplo:
Código PHP:
class AlgunMotor
{
    [...]

    public function 
query($sql){
        
$result mysql_query($sql);

        
$array = array();

        while(
$row mysql_fetch_assoc($result))
                
$array[] = $row;

        return 
Result($array);
    }
}

class 
Result
{
    private 
$resultados = array();

    public function 
__construct($result){
        if(
is_array($result))
            
$this->resultados $result;
    }

    public function 
siguiente(){
        return 
next($this->resultados);
    }

    [...]

Bueno, creo que ahí me supe explicar un poco mejor. De la forma en que lo hice (obviamente falta el Factory) la implementación del motor devuelve un objeto Result cuando se realiza la query y la clase Result termina siendo la misma para todos los motores y sin ninguna implementación especifica. Entiendo que si hiciéramos así perderíamos algunas utilidades según el motor (por ej. mysql_insert_id() ). Si cada motor tuviera su implementación del objeto Result que devuelve aplicaríamos lo que dices de la interface pero si hiciéramos una implementación por motor, de otra forma es innecesario.

Tal vez me este fallando un concepto, pero creo no estar muy errado... favor de corregir si estoy mal.

Saludos.
  #11 (permalink)  
Antiguo 27/06/2007, 10:32
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Mi primer intento de clase

A lo que yo me referia es porque es mas sencillo pasar el identificador del resultado y ya que cada resultado sepa como descargar los mensajes de la base de datos, por ejemplo si te fijas mysql_query, acepta dos parametros, el query y el enlace a la conexion, y te devuelve un identificador de resultado.

mysql_fetch_array por el contrario solo te acepta un parametro que es el identificador de resultado.

Te invito a que leas un poco sobre PDO es una clase muy especifica a como deberia de funcionar un DB Access Layer, ya que te devuelve diferentes clases e implenta el patron Factory.

Saludos.
  #12 (permalink)  
Antiguo 27/06/2007, 10:52
 
Fecha de Ingreso: junio-2005
Mensajes: 981
Antigüedad: 18 años, 10 meses
Puntos: 2
Re: Mi primer intento de clase

Cita:
Iniciado por GatorV Ver Mensaje
A lo que yo me referia es porque es mas sencillo pasar el identificador del resultado y ya que cada resultado sepa como descargar los mensajes de la base de datos, por ejemplo si te fijas mysql_query, acepta dos parametros, el query y el enlace a la conexion, y te devuelve un identificador de resultado.

mysql_fetch_array por el contrario solo te acepta un parametro que es el identificador de resultado.
Si, eso lo sabía, obvie el recuro de la conexión solo por escribir apurado.

Cita:
Iniciado por GatorV Ver Mensaje
Te invito a que leas un poco sobre PDO es una clase muy especifica a como deberia de funcionar un DB Access Layer, ya que te devuelve diferentes clases e implenta el patron Factory.

Saludos.
Acepto. Me voy a poner a buscar info y veo si entiendo todo, cualquier cosa vuelvo

Saludos.
  #13 (permalink)  
Antiguo 27/06/2007, 12:14
 
Fecha de Ingreso: octubre-2003
Mensajes: 540
Antigüedad: 20 años, 6 meses
Puntos: 1
Re: Mi primer intento de clase

Bueno, pero en definitiva, es aceptable como quedó mi clase o no?
  #14 (permalink)  
Antiguo 27/06/2007, 12:17
 
Fecha de Ingreso: marzo-2007
Mensajes: 347
Antigüedad: 17 años, 1 mes
Puntos: 2
Re: Mi primer intento de clase

Tu clase esta bien y completa .

Un saludo
  #15 (permalink)  
Antiguo 27/06/2007, 12:21
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Mi primer intento de clase

Si lees lo que pusimos puede que este "bien" a nivel codigo, pero a nivel implementacion es incorrecta, ya que en teoria debes de manejar una abstraccion mayor para obtener la portabilidad que requiere un objeto, y mas cuando es un DB Access Layer.

Saludos.
  #16 (permalink)  
Antiguo 27/06/2007, 12:33
 
Fecha de Ingreso: marzo-2007
Mensajes: 347
Antigüedad: 17 años, 1 mes
Puntos: 2
Re: Mi primer intento de clase

Hombre, yo me referia a los dos temas, la verdad, a que te referiste a nivel de implementacion?

Un saludo
  #17 (permalink)  
Antiguo 27/06/2007, 12:36
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Mi primer intento de clase

A programar siguiendo el lineamiento de la programacion Orientada a Objetos, que es proveer abstraccion entre objetos, asi puedes reutilizar codigo y no dejas un codigo especifico para algo, que la idea es poder reutilizar en todos los proyectos el mismo codigo.

Saludos.
  #18 (permalink)  
Antiguo 27/06/2007, 12:50
 
Fecha de Ingreso: marzo-2007
Mensajes: 347
Antigüedad: 17 años, 1 mes
Puntos: 2
Re: Mi primer intento de clase

Ahhh, pues en ese caso, te tengo que dar la razon, ya ese es el principal objetivo de la programacion orientada a objetos

Un saludo
  #19 (permalink)  
Antiguo 26/08/2007, 13:02
 
Fecha de Ingreso: octubre-2003
Mensajes: 540
Antigüedad: 20 años, 6 meses
Puntos: 1
Re: Mi primer intento de clase

Habia dejado de lado esto por falta de tiempo ahora busco retomarlo, asi que revivo este topic para consultarles algo..

Cual es la finalidad o en que caso es necesario declarar las variables al comienzo de la clase? Estuve haciendo unas pruebas con esta en particular y con otras que encontre en la web y noto que quitando la declaración de las mismas las clases siguen funcionando correctamente, o al menos eso parece.
  #20 (permalink)  
Antiguo 26/08/2007, 15:22
 
Fecha de Ingreso: noviembre-2003
Mensajes: 798
Antigüedad: 20 años, 5 meses
Puntos: 8
Re: Mi primer intento de clase

Son conceptos OOP Generales, te recomiendo leer sobre conceptos de programación orientados a objetos.

http://www.programacion.net/java/tut...ava_basico/12/

http://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_objetos

La lógica es la misma en PHP5

saludos.
  #21 (permalink)  
Antiguo 26/08/2007, 15:59
 
Fecha de Ingreso: octubre-2003
Mensajes: 540
Antigüedad: 20 años, 6 meses
Puntos: 1
Re: Mi primer intento de clase

Cita:
Iniciado por zsamer Ver Mensaje
Son conceptos OOP Generales, te recomiendo leer sobre conceptos de programación orientados a objetos.

http://www.programacion.net/java/tut...ava_basico/12/

http://es.wikipedia.org/wiki/Program...tada_a_objetos

La lógica es la misma en PHP5

saludos.

Entiendo que es algo básico de POO pero lo desconosco y sinceramente no encuentro respuesta a mi pregunta en los links que aportas. Podrias citar la parte relevante?
  #22 (permalink)  
Antiguo 26/08/2007, 16:33
 
Fecha de Ingreso: noviembre-2003
Mensajes: 798
Antigüedad: 20 años, 5 meses
Puntos: 8
Re: Mi primer intento de clase

En la 1º todo es relevante.

En la segunda, respecto los atributos o "variables propias de una clase" :

Cita:
Propiedad o atributo: contenedor de un tipo de datos asociados a un objeto (o a una clase de objetos), que hace los datos visibles desde fuera del objeto, y cuyo valor puede ser alterado por la ejecución de algún método.
Si realmente quieres aprender OOP vas a tener que acostumbrarte a leer mucho sobre el tema, sugiero que comiences por lo más básico, en google hay mucha información, sólo tienes que buscar.
  #23 (permalink)  
Antiguo 26/08/2007, 16:46
 
Fecha de Ingreso: noviembre-2003
Mensajes: 798
Antigüedad: 20 años, 5 meses
Puntos: 8
Re: Mi primer intento de clase

Un buen punto de partida en OOP PHP5
  #24 (permalink)  
Antiguo 26/08/2007, 17:01
 
Fecha de Ingreso: octubre-2003
Mensajes: 540
Antigüedad: 20 años, 6 meses
Puntos: 1
Re: Mi primer intento de clase

Vuelvo a postear mi duda:

Cita:
Iniciado por Finseneu Ver Mensaje
Cual es la finalidad o en que caso es necesario declarar las variables al comienzo de la clase? Estuve haciendo unas pruebas con esta en particular y con otras que encontre en la web y noto que quitando la declaración de las mismas las clases siguen funcionando correctamente, o al menos eso parece.
La respuesta puede ser que sirve para definir desde donde pueden ser accesados los métodos? Y si esto es verdadero, en el caso de no declararlos es lo mismo que hacerlo como private?
  #25 (permalink)  
Antiguo 27/08/2007, 08:02
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Mi primer intento de clase

Lo que pasa es que PHP es un lenguaje mas "simple" en cuanto a la declaracion de variables, si no declaras una variable esta adquiere por defecto el valor de "publica" pero si luego te quieres mudar a otro lenguaje como C#, o Java, encontraras que si no declaras las variables y su visibilidad, el compilador te dara error.

Asi que por ti mismo lo mejor es que te acostumbres a declarar las variables asi inclusive tu codigo es mas limpio ya que tienes que documentar las variables por decir:
Código PHP:
class Table {
       
/**
        * $columns
        *
        * Variable privada arreglo, especifica las columnas de la tabla
        **/
       
private $columns = array();
       
/**
        * $rows
        *
        * Variable privada arreglo, especifica las filas de la tabla
        **/
       
private $rows = array();

Asi mantienes tu clase bien documentada y estructurada, y luego no te pierdes al saber que valor tiene una variable o cual es su uso.

Saludos.
  #26 (permalink)  
Antiguo 27/08/2007, 12:00
 
Fecha de Ingreso: octubre-2003
Mensajes: 540
Antigüedad: 20 años, 6 meses
Puntos: 1
Re: Mi primer intento de clase

Entonces es solo una cuestión de "buenas costumbres"?
  #27 (permalink)  
Antiguo 27/08/2007, 12:03
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Mi primer intento de clase

En PHP si, pero como te explico, si quieres documentar y sacar tus clases al publico lo mejor es que esten bien estructuradas para que cualquier programador pueda identificar en donde estan.

Ahora por reglas de OOP se recomienda que los atributos no sean pubicos y que sean privados y usar los famosos setter/getter y para especificarlos privados la unica forma es declarandolos.

Saludos.
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 06:03.