Loading




Enviar respuesta 
 
Calificación:
  • 0 votos - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Clase de conexion a DB
 
04-08-2011, 11:08 PM
Mensaje: #1
Clase de conexion a DB
Hace unos dos meses comencé a desarrollar mi propio CRM intento de mini framework para cosas bastante específicas.

El proyecto esta bastante avanzado, está programado en PHP-OO y REST siguiendo las recomendaciones de codificación de Zend, recayendo en apache(.htaccess) la responsabilidad de simular las urls como recursos.

Luego de leer mucho sobre el manejo de conexiones en PHP, y dado que no necesito de persistencia, decidí que mi clase de conexión tenga un método conectar y otro desconectar para liberar las conexiones lo antes posible. Por el momento las aplicaciones de mi aplicación manejan gran volumen de datos y pocos usuarios, pero una futura aplicación podría requerir lo contrario.

Si hay alguien con más experiencia me gustaría escuchar recomendaciones o críticas, o puntos de vista diferentes sobre la forma de abordar conexiones concurrentes.

Cabe aclarar que no se a donde va a llegar este proyecto, ni pretende convertirse en algo más grande. Lo comencé como una forma de investigar y aplicar métodos de trabajo, y conocimientos adquiridos de libros en los últimos meses, amén del rédito económico de haberlo ubicado 1-wink

Queda mucho por pulir y codificar en este experimento, y si alguien está interesado en algo de lo que mencione que pregunte nomas 1-smile

A continuación pego mi clase de conexión a la DB con algunos extras, funciona sin agregar nada, ConexionDB.php:
Código PHP:
<?php

/* DBSERVER servidor donde se encuentra mysql */
define('DBSERVER','localhost'); 

/* DBUSER usuario valido para conectarse a mysql */
define('DBUSER','user'); 

/* DBPASS clave de usuario de mysql */
define('DBPASS','pass'); 

/* DBBASE base de datos a utilizar */
define('DBBASE','base'); 

class 
ConexionDB
{
    private 
$conexion;

    public function 
__get($var){
        return (
$var!="instance" && isset($this->$var))?$this->$var:false;
    }
    
    
    public function 
conectar(){
        
$this->conexion mysql_connect(DBSERVER,DBUSER,DBPASS);
        if(!
$this->conexion) return false//no se puede conectar a la base de datos
        
else mysql_select_db(DBBASE,$this->conexion); 
        
        return 
true;
    } 
/*  Fin de metodo conectar */
     

    
public function consulta($sql){
        
$row mysql_query($sql,$this->conexion); 
        
$filas mysql_affected_rows();
        
$query $this->tipoQuery($sql);
        
//var_export($row); var_export($filas);
        
if(!$row)
            
$resultado="Error sql: ".mysql_error();
        elseif(
$filas > -&& ($query=='INSERT' || $query=='UPDATE'))
                
$resultado=$filas//si insert o update ok
        
elseif($row == true)
                
$resultado=true//si create, drop o tuncate ok
        
elseif(@mysql_num_rows($row) > 0)
                 while(
$aux = @mysql_fetch_assoc($row))
                       
$resultado[]=$aux//si select tiene datos
        
else $resultado=false//select, insert o update: vacios, sin exito, sin coincidencias y sin errores
        //var_export($resultado);
        //mysql_free_result($row);
        
return $resultado;
    } 
/*  Fin de metodo consulta */


    
public function tipoQuery($query){
        
$query trim($query,'\t\n\r');
        
$query explode(' ',$query);
        return 
strtoupper($query[0]);
    }


    public function 
filtraTildes($texto,$tildes){
        
// Iniciamos un array de asociaciones
        
$quitar=array('á'=>'a;','é'=>'e;','í'=>'i;','ó'=>'o;','ú'=>'u;','Á'=>'A;','É'=>'E;','Í'=>'I','Ó'=>'O;','Ú'=>'U');
        
$cambiar=array('á'=>'&aacute;','é'=>'&eacute;','í'=>'&iacute;','ó'=>'&oacute;','ú'=>'&uacute;''Á'=>'&Aacute;','É'=>'&Eacute;','Í'=>'&Iacute;','Ó'=>'&Oacute;','Ú'=>'&Uacute;','ö'=>'&ouml;','ü'=>'&uuml;','Ö'=>'&Ouml;','Ü'=>'&Uuml;','ñ'=>'&ntilde;','Ñ'=>'&Ntilde;''×'=>'&times;','Ø'=>'&Oslash;','¿'=>'&iquest;','¡'=>'&iexcl;','©'=>'&copy;','®'=>'&reg;','°'=>'&deg;','•'=>'&bullet;','º'=>'&ordm;','¢'=>'&cent;');
        if(
$tildes==true$reemplazo=$cambiar;
        else 
$reemplazo=$quitar;
        
// Saneamos los parametros GET
        
foreach ($reemplazo as $key => $value){
            
$texto str_replace($key,$value,$texto);
        }    
        return 
$texto;
    } 
/*  Fin de metodo filtraTildes */
    
    
    
public function filtraHtml($texto){
        return 
htmlspecialchars($this->filtraTildes($texto,true));
    } 
/*  Fin de metodo filtraHtml */
    
 
    
public function filtraSql($var){
        if(
is_array($var)){
            foreach(
$var as $key => $value){
                
$var[$key]=mysql_real_escape_string($value);
            }
        }else 
$var=mysql_real_escape_string($var);
        
        return 
$var;
    } 
/*  Fin de metodo filtraSql */
    

    
public function toUTF8($string){
        if(
$this->isUTF8($string)==false)
            return 
utf8_encode($string); 
        else return 
$string;       
    }


    public function 
isUTF8($string){
        for(
$idx=0$strlen=strlen($string); $idx<$strlen$idx++){
            
$byte ord($string[$idx]);

            if(
$byte 0x80){
                if((
$byte 0xE0) == 0xC0)
                    
$bytes_remaining 1// 2 byte char
                
elseif(($byte 0xF0) == 0xE0)
                    
$bytes_remaining 2// 3 byte char
                
elseif(($byte 0xF8) == 0xF0)
                    
$bytes_remaining 3// 4 byte char
                
else return false;
                 
                if (
$idx $bytes_remaining >= $strlen)
                    return 
false;
                 
                while (
$bytes_remaining--){
                    if((
ord($string[++$idx]) & 0xC0) != 0x80)
                        return 
false;
                }
            }
        }
         
        return 
true;
    } 
/* Fin de metodo isUTF8 */


    
public function desconectar(){
        
mysql_close($this->conexion);
    } 
/*  Fin de metodo desconectar */
  


Su uso:
$SQL = new ConexionDB();
$consulta = "select clave from usuarios where ...;";
$SQL->conectar();
$SQL->consulta($consulta);
$SQL->desconectar();
.........
$consulta = "update ...;";
$SQL->conectar();
$SQL->consulta($consulta);
$SQL->desconectar();

Saludos

- La seguridad es más importante que la usabilidad. En un mundo perfecto, nadie debería ser capaz de utilizar nada.
Encuentra todos sus mensajes
Cita este mensaje en tu respuesta
 
05-08-2011, 02:30 PM (Este mensaje fue modificado por última vez en: 05-08-2011 02:33 PM por p_eter.)
Mensaje: #2
RE: Clase de conexion a DB
Hola, 2 meses y redondeando, que bien!
Me pregunto que será lo especial que pidieron al CRM.
¿A que te refieres cuando dices "recayendo en apache(.htaccess) la responsabilidad de simular las urls como recursos." ?
Sobre la base, si maneja transacciones creo convendrá InnoDB como motor para MySQL.
Visita su sitio web Encuentra todos sus mensajes
Cita este mensaje en tu respuesta
 
05-08-2011, 03:42 PM
Mensaje: #3
RE: Clase de conexion a DB
Hola p_eter, al diseñar la aplicacion con REST (ver tambien), utilizamos urls amigables(acá entra apache) para simular recursos del servidor.

Los servidores web soportan las operaciones GET, POST, PUT, UPDATE y DELETE, pero por seguridad algunas están desabilitadas por defecto.

Utilizando REST podemos realizar la accion DELETE http://miweb.com/usuario/Pablo para borrar a Pablo, La forma de hacerlo utilizando solo GET y POST sería algo asi:
GET http://miweb.com/usuario/editar/pablo
POST id="3" accion="delete"

Por GET solo obtenemos informacion, es decir, obtenemos los datos del usuario Pablo en un formulario para modificar, el formulario a su vez puede tener guardar, borrar etc, entre las acciones disponibles, y devuelve datos y acciones. Nunca pasamos datos por GET si trabajamos con REST.

Visto por apache esto quedaría así:
La url http://miweb.com/usuario/editar/pablo se rearmaría con redirectrule de la forma http://miweb.com/index.php?router=usuario/editar/pablo

Luego pasamos la variable $_GET['router'] que contiene usuario/editar/pablo a un despachador que interpretará la forma de devolver los datos que puede ser:
+aplicacion
|-+modulo = usuario
...|-+opcion = editar
......|--dato = pablo

Con respecto a las aplicaciones en este momento lo estoy utilizando para hacer una web, una aplicacion de control de stock, una migracion de rhpro a bejerman y en cuanto tenga tiempo una aplicacion de gestion de consumibles y recargables.

Saludos

- La seguridad es más importante que la usabilidad. En un mundo perfecto, nadie debería ser capaz de utilizar nada.
Encuentra todos sus mensajes
Cita este mensaje en tu respuesta
 
05-08-2011, 06:33 PM
Mensaje: #4
RE: Clase de conexion a DB
A ver si te aporto algo...

Según me han dicho, la mayoría de las base de datos "grandes" trabajan con un pull de conexiones, esto es, dejan siempre una serie de conexiones "abiertas" y cuando llega un cliente se la asigna una, cuando el cliente termina no se cierra la conexión, sino que "desasocia" al cliente. De esta forma se evitan el costo de andar abriendo y cerrando conexiones. Osea que si tu base de datos usa un pull de conexiones tenés que abrir y cerrar la conexión inmediatamente, ya que si la dejas abierta ocupás una conexión que podrías no estar usando y si hay muchos clientes el servidor de base de datos va a abrir mas conexiones y perder mas tiempo.

Osea que podés poner el código de la conexión adentro del método consulta y de paso simplificás el código.
Visita su sitio web Encuentra todos sus mensajes
Cita este mensaje en tu respuesta
 
05-08-2011, 07:25 PM
Mensaje: #5
RE: Clase de conexion a DB
Lo estuve meditando un poco y si no se utiliza persistencia, en php al finalizar el script finaliza la conexión a la DB, es más, si el usuario aborta mediante el botón stop del navegador o cerrando la pestaña la conexion es interrumpida ya que el browser avisa al web server que la conexión ha finalizado por el cliente.

Otro punto es el manejo de errores, podría crear un nuevo método que conecte y si tiene exito ejecute la consulta, pero si devuelve 'false' se me complica saber si falló la consulta o la conexión a la DB.

Luego tenemos la carga de grandes lotes de datos, si creamos consultas demasiado grandes pueden abortarse por timeout(amén de otros problemas que he tenido con gran volumen de datos), si el servidor es nuestro tocamos el php.ini, pero si la aplicación se encuentra alojada en un hosting comercial no podemos cambiar esto. Abririamos y cerraríamos cientos de conexiones en lugar de iterar una conexión abierta.

Es un punto bastante bueno para investigar, voy a ver si averiguo como resolvieron esto en otros frameworks 1-smile

Con respecto a pools de conexiones y balanceo de carga ya hay algo, pero por el momento no lo requiero y no quiero sobredimensionar. Cuando lo necesite crearé una nueva clase, en este proyecto me propuse no programar a futuro y preveer lo minimo indispensable 1-wink

- La seguridad es más importante que la usabilidad. En un mundo perfecto, nadie debería ser capaz de utilizar nada.
Encuentra todos sus mensajes
Cita este mensaje en tu respuesta
Enviar respuesta 


Salto de foro:


Usuario(s) navegando en este tema: 1 invitado(s)
Contáctanos | Portal de Noticias | Volver arriba | Volver al contenido | Archivo (Modo simple) | Sindicación RSS