Foros del Web » Programando para Internet » PHP »

Aporte: Clase para manejar mySQL

Estas en el tema de Aporte: Clase para manejar mySQL en el foro de PHP en Foros del Web. Hace poco que estoy intentando desarrollar un microframework para uso personal (crear algunas webs, sistemas de usuarios y cosas comunes) que puede que suba dentro ...
 
Antiguo 24/08/2011, 03:16
3nr1c
Invitado
 
Mensajes: n/a
Puntos:
Aporte: Clase para manejar mySQL

Hace poco que estoy intentando desarrollar un microframework para uso personal (crear algunas webs, sistemas de usuarios y cosas comunes) que puede que suba dentro de algún tiempo, pero de momento quiero mostraros la clase mysql, por si alguien la quiere aprovechar.

Código PHP:
class mysql {
    
        var 
$link;
        var 
$host;
        var 
$user;
        var 
$pasw;
        var 
$database;
        
        function 
mysql(){            
            
$args=func_get_args();
            if(isset(
$args[2])){
                
$this->host = $args[0];
                
$this->user = $args[1];
                
$this->pasw = $args[2];
                if(isset(
$args[3])){
                    
$this->database = $args[3];
                }
                
                
$this->connect();
            }
        }
        
        function 
connect(){
            
$args=func_get_args();
            if(isset(
$args[2])){
                
$this->host = $args[0];
                
$this->user = $args[1];
                
$this->pasw = $args[2];
            }
            
$this->link = mysql_connect($this->host,$this->user,$this->pasw)or die(mysql_error());
            if(isset(
$args[3])){
                
$this->database = $args[3];
            }
            if(isset(
$this->database)){
                
mysql_select_db($this->database,$this->link)or die(mysql_error());
            }
        }
        
        function 
change_database($new_database){
            
mysql_select_db($new_database,$this->link)or die(mysql_error());
        }
        
        var 
$result;
        
        function 
query($string){//interfaz de bajo nivel
            
$query = mysql_query($string)or die(mysql_error());
            if(
$query!=NULL){
            if(
mysql_num_rows($query)==1){
                
$return = mysql_fetch_array($query);
            }else{
                
$i=0;
                while(
$row = mysql_fetch_array($query)){
                    
$return[$i] = $row;
                    
$i++;
                }
            }
            if(!isset(
$return)){
                
$return = 'No results';
            }
            
$this->result = $return;
            return 
$return;
            }
        }
        
        private function 
createQuery($array){
            
$args = $array;
            if(isset(
$args[0])){
                if(
$args[0]=='select'){
                    
array_shift($args);
                    if(
preg_match('/^!.*$/',$args[0])){
                        
$dis = preg_replace('/^!/','',$args[0]);
                        
$query = 'select distinct '.$dis.' from ';
                        
array_shift($args);
                    }else{
                        
$query = 'select * from ';
                    }
                }elseif(
$args[0]=='delete'){
                    
array_shift($args);
                    
$query = 'delete from ';
                }
                
$query .= $args[0];//table
                
                //where clause:
                
if(isset($args[1]) and !is_bool($args[1])){
                    if(!
preg_match('/^@/',$args[1]) && !preg_match('/^#/',$args[1])){
                    if(
preg_match('/^where /',$args[1])){
                        
$query .= $args[1];
                        
$bool=false;
                    }elseif(
preg_match('/[A-z]/',$args[1]) && isset($args[2])){
                        
$query .= ' where '.$args[1];
                        
$where = explode(',',$args[2]);
                        if(
preg_match('/^\/.*\/$/',$where[0])){
                            
$regexp = preg_replace(array('/^\//','/\/$/'),'',$where[0]);
                            
$query .= ' regexp "'.$regexp.'"';
                        }else{
                            
$query .= ' = "'.$where[0].'"';
                        }
                        for(
$i=1, $num=count($where);$i<$num;$i++){
                            
$query .= ' or '.$args[1].' ';
                            if(
preg_match('/^\/.*\/$/',$where[$i])){
                                
$regexp = preg_replace(array('/^\//','/\/$/'),'',$where[$i]);
                                
$query .= ' regexp "'.$regexp.'"';
                            }else{
                                
$query .= ' = "'.$where[$i].'"';
                            }
                        }
                        
$bool=true;//revision de los otros argumentos
                    
}else{
                        
$query .= ' where id = "';
                        
$ids = explode(',',$args[1]);
                        
$query .= $ids[0].'"';
                        for(
$i=1, $num=count($ids);$i<$num;$i++){
                            
$query .= ' or id = "'.$ids[$i].'"';
                        }
                        
$bool=false;
                    }
                    }
                }
                if(isset(
$bool) && $bool){//agumentos restantes de la cláusula where
                    
for($i=3,$num=count($args);$i<$num;$i+2){
                        if(!isset(
$args[$i]) or empty($args[$i]) or
                        
preg_match('/^@.*/',$args[$i]) or preg_match('/^#.*/',$args[$i])){
                            break;
                        }else{
                            if(!isset(
$args[$i+1]) or empty($args[$i+1]) or
                            
preg_match('/^@.*/',$args[$i+1]) or preg_match('/^#.*/',$args[$i+1])){
                                break;
                            }else{
                                if(
preg_match('/^&.*/',$args[$i])){
                                    
$and = preg_replace('/^&/',' and ',$args[$i]);
                                    
$query .= $and;
                                }else{
                                    
$query .= ' or '.$args[$i];
                                }
                                
$where = explode(',',$args[$i+1]);
                                if(
preg_match('/^\/.*\/$/',$where[0])){
                                    
$regexp = preg_replace(array('/^\//','/\/$/'),'',$where[0]);
                                    
$query .= ' regexp "'.$regexp.'"';
                                }else{
                                    
$query .= ' = "'.$where[0].'"';
                                }
                                for(
$i=1, $num=count($where);$i<$num;$i++){
                                    
$query .= ' or '.$args[1].' ';
                                    if(
preg_match('/^\/.*\/$/',$where[$i])){
                                        
$regexp = preg_replace(array('/^\//','/\/$/'),'',$where[$i]);
                                        
$query .= ' regexp "'.$regexp.'"';
                                    }else{
                                        
$query .= ' = "'.$where[$i].'"';
                                    }
                                }
                            }
                        }
                    }
                }
                
                
//cláusula order by
                
$p_last=count($args)-2;
                if(
preg_match('/^@.*sc$/',end($args)) or 
                  (isset(
$args[$p_last]) &&  preg_match('/^@.*sc$/',$args[$p_last]))){
                    if(
preg_match('/^@.*sc$/',end($args))){
                        
$p = explode(' ',end($args));
                    }else{
                        
$p = explode(' ',$args[$p_last]);
                    }
                    
$o_by = preg_replace('/^@/','',$p[0]);
                    if(!isset(
$p[1])){
                        
$p[1]='asc';
                    }
                    
$query .= ' order by '.$o_by.' '.$p[1];        
                }
//cláusula limit
                
if(preg_match('/^#.*/',end($args))){
                    
$limit = preg_replace('/^#/','',end($args));
                    
$query .= ' limit '.$limit;
                }
            }
            return 
$query;
        }
        
        function 
select(){
            
$args=func_get_args();
            
array_unshift($args, 'select');
            
            
$query = $this->createQuery($args);
            
            
$result = $this->query($query);
            
//return $query;
            
return $result;
            
//return 'Error: no args passed to select() method';
        
}
        
        function 
delete(){
            
$args=func_get_args();
            
$num_args=func_num_args();
            if(
$num_args<=1){
                return 
'Security error: delete a complete table requires two arguments';
            }else{
                if(
gettype($args[1])=='bool' && $args[1]){
                    
$query = 'delete from '.$args[0];
                }elseif(
gettype($args[1])=='bool' && !$args[1]){
                    return 
'Security error: delete a complete table requires two "true" elements';
                }else{
                    
array_unshift($args, 'delete');
                    
                    
$query = $this->createQuery($args);
                }
            }
            if(isset(
$query)){
                
mysql_query($query)or die(mysql_error());
            }
        }
        
        function 
truncate(){
            
$args=func_get_args();
            
$num_args=func_num_args();
            if(
$num_args<=1){
                return 
'Security error: truncate a table requires two arguments';
            }else{
                if(
$args[1]){
                    
$query = 'truncate table '.$args[0];
                }
            }
            if(isset(
$query)){
                
mysql_query($query) or die(mysql_error());
            }
        }
        
        function 
insert(){
            
$args=func_get_args();
            if(isset(
$args[1])){
                
$query = 'insert into '.$args[0];
                
$keys=' (';
                
$values=' values (';
                foreach(
$args[1] as $key=>$value){
                    
$keys.=$key.',';
                    
$values.='\''.$value.'\',';
                }
                
$keys = substr($keys,0,(strlen($keys)-1)).')';
                
$values = substr($values,0,(strlen($values)-1)).')';
                
$query.= $keys.$values;
                
mysql_query($query)or die(mysql_error());
            }
        }
    } 

Es algo larga, pero merece la pena.

Es capaz de trabajar tanto a bajo nivel (un simple mysql_query), como a un nivel más alto. Os pongo la referencia de los métodos:

Código PHP:
$mysql = new mysql($host,$user,$pasw,$database);
$mysql->select([$distinct,]$table[,$row,$matches[,$row2,$matches[, ...]]][,$orderby][,$limit]);
$mysql->delete($table,$row,$matches[,$row,$matches[,..]][,$limit]);
$mysql->truncate($table,$bool);//el $bool es por seguridad
$mysql->insert($table,array($key=>$value));//todavía tengo que mejorar esto 
Para ir acabando, un par de cosillas importantes sobre la referencia:
  • $distinct es una cadena que empieza por '!' y sigue con las columnas a seleccionar, separadas por comas
  • $matches son todas las coincidencias deseadas para el $row, separadas por comas. Se pueden usar expresiones regulares (rodeadas por / y /) y mezclar cadenas exactas y expresiones regulares
  • $row2 (y todos los siguientes) puede llevar delante '&', que hará que sea necesario cumplir con todos los $matches pasados como argumentos (where ... and ...), o no llevar nada (where ... or ...).
  • $orderby tiene que empezar por '@', luego seguido de la columna índice
  • $limit tiene que empezar por '#', luego seguido de dos numeros separados por comas

Es algo difícil de comprender... Pero uno se acostumbra rápido.

Y si no es mucho pedir... podríais postear si encontráis algún bug o mejora posible? gracias

Que podáis hacer uso de la clase

Saludos
 
Antiguo 24/08/2011, 03:42
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 18 años, 6 meses
Puntos: 253
Respuesta: Aporte: Clase para manejar mySQL

Buen aporte,

La verdad que yo también pensé en su día en montar algo de este estilo, pero al final siempre lo dejo para otro momento. Las consultas SQL son tan variadas y tienen tantos matices y situaciones diferentes, que siempre acabo por poner un select, insert, delete y update que reciba la sentencia y ya.

Yo añadiría una cosa a tu clase: un control de errores un poco más extenso. En la clase que yo utilizo para la base de datos siempre añado una variable $errormsg y un par de métodos SetErrorMsg, GetErrorMsg, CleanErrorMsg, PrintErrorMsg y ConcatErrorMsg. Con esto y poco de control, puedes tener una traza de lo que ha ocurrido en cada consulta o conexión, tipo LOG. Así, cada vez que ejecuto una función susceptible de fallar, concateno el resultado a la cadena de error, ya sea avisando del éxito o del error. Así, cuando hay un error e imprimo toda la cadena, sé exactamente qué operaciones funcionaron y cuál fue la del error, así como el error en sí, sacado con mysql_error.

Espero que te agrade el consejo y suerte.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
 
Antiguo 24/08/2011, 03:50
3nr1c
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Aporte: Clase para manejar mySQL

Ante todo, gracias por la crítica

Sobre los mensajes de error, crees que sería posible hacer una clase sólo para los errores, y que fuera 'padre' de la clase mysql?

Me explico:

Código PHP:
Ver original
  1. class errorlog{
  2. ...
  3. }
  4.  
  5. class mysql extends errorlog{
  6. ...
  7. }
 
Antiguo 24/08/2011, 04:11
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 18 años, 6 meses
Puntos: 253
Respuesta: Aporte: Clase para manejar mySQL

No tiene por qué ser clase padre, puedes hacer una clase ErrorLog diferente y añadirla como un atributo de tu clase MySQL, usándola como un objeto, simplemente tendrías que incluir el fichero de la clase de errores y usar sus métodos dentro de la clase de la base de datos. Es una buena opción, ya que así podrás usar la clase ErrorLog en otros contextos, no sólo con bases de datos.

Ten en cuenta que esto te permite no sólo incuir mensajes de error, si no también de éxito. Por ejemplo, si haces una inserción y todo termina correctamente, puedes incluir en el mensaje que la inserción ha sido correcta y mostrarla al usuario. De hecho yo mantengo los nombres con Error delanta, pero ya no la utilizo sólo para error, más bien como Log.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?

Etiquetas: clase, manejar, mysql, sql, usuarios
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

SíEste tema le ha gustado a 1 personas



La zona horaria es GMT -6. Ahora son las 08:55.