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 ...
  #1 (permalink)  
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
  #2 (permalink)  
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: 16 años, 1 mes
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?
  #3 (permalink)  
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. }
  #4 (permalink)  
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: 16 años, 1 mes
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 03:25.