entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

3votos

Agregar consultas SQL en metodos de una clase - PHP

Estoy empezando a utilizar Clases, Namespaces y demas usando Php 5.3

Quisiera saber si es una buena practica utilizar consultas dentro de los metodos de una clase.

Por ejemplo algo asi (En el ejemplo esta puesto con mysql_ pero voy a utilizar la clase mysqli),

class Categoria
{
private $nombre, $id;

function __construct()
{
    $this->id=0;
    $this->nombre="";
}

function Initialize($cod=0)
{
    $this->id=intval($cod);
    if($this->id!=0) 
    {
        //Obtengo todos los datos de la categoria
        $query="SELECT * FROM Categorias WHERE cat_id=".$this->id;
        $result=mysql_query($query);
        if(mysql_num_rows($result)>0)
        {
            $cat=mysql_fetch_assoc($result);
            $this->nombre=$cat['cat_name'];
        }else
        {
            $this->id=0;
        }
        mysql_free_result($result);         
    }
}

function Get_Id()
{
    return $this->id;
}

function Get_Name()
{
    return $this->nombre;
}

function Set_Name($name="")
{
    if(trim($name)!="")
    {
        $this->nombre=htmlentities(trim($name),ENT_QUOTES);;
    }
}

function Get_Item_List()
{
    //Obtengo todos los articulos correspondientes a la categoria
    $query="SELECT art_id AS id FROM Articulos WHERE art_cat_id=".$this->id;
    $result=mysql_query($query);
    if(mysql_num_rows($result)>0)
    {
        $listado=array();
        $i=0;
        while($i < mysql_num_rows($result)) 
        {
            $aux=mysql_fetch_assoc($result);
            $art= new Articulo;
            $art->Initialize($aux['id']);
            $listado[]=$art;
            $i++;
        }
        return $listado;
    }
}

function Get_Total()
{
    if($this->id!=0) 
    {
        $query="SELECT COUNT(*) AS Total FROM Articulos WHERE art_cat_id=".$this->id;
        $result=mysql_query($query);
        $tot=mysql_fetch_assoc($result);
        return $tot['Total'];
    }else 
    {
        return 0;
    }
}   

function Get_Total_Ofertas()
{
    if($this->id!=0) 
    {
        $query="SELECT COUNT(*) AS Total FROM Articulos WHERE art_cat_id=".$this->id." AND art_oft_id IS NOT NULL";
        $result=mysql_query($query);
        $tot=mysql_fetch_assoc($result);
        return $tot['Total'];
    }else 
    {
        return 0;
    }
}

function Get_Total_Disabled() 
{
    if($this->id!=0) 
    {
        $query="SELECT COUNT(*) AS Total FROM Articulos WHERE art_cat_id=".$this->id." AND art_est_id=0";
        $result=mysql_query($query);
        $tot=mysql_fetch_assoc($result);
        return $tot['Total'];
    }else 
    {
        return 0;
    }
}

private function Exist()
{
    if($this->nombre!="")
    {
        $query="SELECT * FROM Categorias WHERE cat_name LIKE '".$this->nombre."'";
        $result=mysql_query($query);
        return (mysql_num_rows($result)>0)? true : false;
    }else 
    {
        //Aca va un objeto Error            
        return false;
    }
}

private function Insert()
{
    if(!$this->Exist())
    {
        $query="INSERT INTO Categorias(cat_name) VALUES ('".$this->nombre."')";
        $result=mysql_query($query);
        return (mysql_errno()==0)?true:false;
    }else 
    {
        return false;
    }
}

function Save()
{
    if($this->id==0) 
    {
        return $this->Insert();
    }
}

function Delete()
{
    if($this->Exist())
    {
        $query="DELETE FROM Categorias WHERE cat_id=".$this->id;
        $result=mysql_query($query);
        return (mysql_errno()==0)?true:false;
    }else 
    {
        return false;
    }
}
}

4 Respuestas

2votos

Leonardo-Tadei Puntos227320

Hola Ángela,

en respuesta a tu pregunta, no es una buena práctica tener llamadas a la base de datos en un diseño en Objetos.

Ojeé los comentarios a las otras respusetas y si no entiendo mal, lo que estás queriendo hacer es un software simple y aplicar buenas prácticas de Ingenieria del Software usando el paradigma de Programación Orientada a Objetos.

Siendo este el caso, tus clases deberían hacer lo que el Modelo requiere según un buen diseño basado en responsabilidades, y no es un enfoque saludable pensar que la Categoría deba encargarse de las conexiones a la DB ni de las consultas, ambas cosas que tienen poco que ver con el modelo.

Sin conocer más que esta clase, puedo afirmarte además que la clase Categoría tiene una crisis de identidad: responde tanto a cuestiones sobre sí misma como a cuestiones sobre Artículos, siendo que no hay una agregación o composición con una Colección de Artículos. Para terminar sobre esta disgresión, aplicando el principio KISS, es equivalente y más simple etner un Artículo que tenga una agregación con una Categoría, que una Categoría que tenga una agregación o composición de una Colección de Artículos.

Volviendo al tema, lo ideal para resolver la cuestión de la persistencia en PHP (vamos, que las cosas se guarden en una DB) es implementar o usar un Mapeador Objeto/Relacional y delegar en el la parte de las querys, para poderte concentrar en el Modelo y la solución al software que estás implementando.

Si te interesa ese camino, te pongo el enlace a un ORM que construí bajo licencia GPL que hace Persistencia No Invasiva y por Alcance: https://github.com/PegasusTech/Persistent

Nosotros lo usamos acá para proyectos comerciales que están en producción hace ya un par de años. Permite trabajar y testear Objetos puros que implementan la solución al problema.

Aceptaré gustoso críticas, consultas y sobre todo ejemplos de uso para publicar ;-)

0voto

Angela comentado

Muchas gracias Leonardo, era justamente esto lo que queria saber.

0voto

rubengc Puntos1090

Es la mejor forma de evitar repetir el mismo código constantemente

Te dejo una clase bastante completa
PHP MySQL Class

0voto

Angela comentado

La verdad es que no le encuentro el sentido a esta clase, sigue utilizando mysql, cuando desde php.net estan avisando que a partir de php 5.5 va a ser obsoleta, y es lo mismo que utilizar la clase mysqli.

Gracias pero no es lo que preguntaba.

1voto

elias_leyton Puntos2260

Te recomiendo desde ya ir viendo y aprendiendo algun Framework sobre PHP como codeigniter.

Saludos

0voto

Angela comentado

Estoy empezando a leer la documentacion de Symphony, pero como menciona la documentacion que es para proyectos grandes - y este no lo es - decidi pempezar a probar con programacion orientada a objetos para de a poco irme metiendo en el tema.

Igual esto tampoco responde mi pregunta :(

0voto

elias_leyton comentado

Se que no responde tu pregunta, mi objetivo no era ese exactamente, si no como concejo, porque si estas viendo esas cosas al emezar, es un momento adecuado para ir mirando otras formas de desarrollar software.

0voto

Angela comentado

Te agradezco, ya me lo habian recomendado. Pero como el proyecto no era grande, sino mas bien simple, mi idea fue ponerme a programarlo orientado a objetos.

Tengo la inquietud de saber si es una mala practica agregar consultas SQL a los metodos de las clases, teniendo en cuenta que dependen de una conexion que la clase no realiza por si sola.

0voto

elias_leyton comentado

Para mi las malas practicas estan contextualizadas en un ambiente de desarrollo con estandares, con modelos de software, metodologias, etc.

Como tu has repetido, es un proyecto simple, no es exacto analizar si es o no una buena practica, ya que si es lo que tu necesitas, esta bien, no hay mayor cuestionamiento, ahora si lo que tu quieres es programar con convenciones por mas simple que sea, ocupa un Framework.

No se si se entiende.

0voto

toni_michel_caubet comentado

+1 Por codeIgniter

2votos

no es que sea inapropiado hacer consultas SQL dentro de una clase, mas que nada, porque ¡en algun sitio habra que hacerlas!. el problema es que 'teoricamente' orientas tu codigo a objetos para 'independizar' trozos de codigo, y ahora mismo tu objeto es dependiente de que exista una conexion abierta a la BBDD (o sea, has tenido que hacer un mysql_connect y un mysql_select_db) ANTES de llamar a ninguna funcion.

Te recomendaria que usaras el patron SINGLETON para encapsular las consultas a las BBDD, usaras esa clase singleton para realizar las consultas y que dicha clase devolviera un array asociativo con las filas devueltas por el mysql_query.

Tambien puedes fabricarte un ORM para cada una de las tablas, pero asi pierdes los JOINS.

en definitiva, no esta mal lo que has hecho (como te dije ¡en algun lado habra que hacer las consultas SQL!), pero no controlas varias cosas (conexion a la BBDD, resultados incorrectos de la BBDD).

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta