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

Pregunta de principiante...

Estas en el tema de Pregunta de principiante... en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Cita: Es un error comun en disenios de tu clase DB como la que hiciste, y para remediarlo lo comun es que cada metodo Consulta ...

  #31 (permalink)  
Antiguo 13/08/2007, 15:37
Avatar de Carxl
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: Bogotá
Mensajes: 2.993
Antigüedad: 18 años, 6 meses
Puntos: 70
De acuerdo Re: Pregunta de principiante...

Cita:
Es un error comun en disenios de tu clase DB como la que hiciste, y para remediarlo lo comun es que cada metodo Consulta (o Query) te devuelva un objeto Recordset donde puedas ciclar, asi aislas el problema y puedes guardar y enviar Querys multiples.
Trato de entenderte , osea que el hacer esto:
Código PHP:
$a->consultar("select * from articulos where id_artclo='$arti'");
    
$row=$a->obtenerDatos();
    
$a->consultar("select * from articulos order by id_artclo desc limit 6");
    
$raw=$a->obtenerDatos();
    
$a->consultar("select * from comentarios,usuarios where id_artclo='$arti' and usuarios.id_usrio=comentarios.id_usrio");
    
$ruw=$a->obtenerDatos();
    
$a->consultar("select count(*) from comentarios where id_artclo='$arti'");
    
$num=$a->obtenerDatos(); 
Por como hice mi clase està mal? Asì no deberìa utilizarla? Tiene info de lo que me dices?? recordset?

Saludos!
__________________
Hay 10 tipos de personas, los que entienden binario y los que no. (Anónimo)
www.programandoweb.com

Última edición por Carxl; 13/08/2007 a las 15:50
  #32 (permalink)  
Antiguo 13/08/2007, 15:56
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 8 meses
Puntos: 2135
Re: Pregunta de principiante...

Si el disenio de tu clase BD esta mal, ya que solo te permite hacer 1 consulta y descargar datos, posteriormente si haces otra consulta te sobreescribe el valor anterior por lo que si intentas descargar datos sera de la anterior.

Solo es cuestion de aplicar un poco de logica algo asi:
Código PHP:
$resultado $a->Consulta"SELECt..." );
$resultado2 $a->Consulta"OtroSelect.." );

while( 
$row $resultado->fetchRow() ) {

}

while( 
$row2 $resultado2->fetchRow() ) {


Un ejemplo basico de una clase result seria:
Código PHP:
class Resultset {
      private 
$result null;
      public function 
__construct$resource ) {
            
$this->result $resource;
      }

      public function 
fetchRow() {
            return 
mysql_fetch_array$this->result );
      }

Saludos..
  #33 (permalink)  
Antiguo 13/08/2007, 16:39
Avatar de Carxl
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: Bogotá
Mensajes: 2.993
Antigüedad: 18 años, 6 meses
Puntos: 70
Re: Pregunta de principiante...

Cita:
Iniciado por GatorV Ver Mensaje
Si el disenio de tu clase BD esta mal, ya que solo te permite hacer 1 consulta y descargar datos, posteriormente si haces otra consulta te sobreescribe el valor anterior por lo que si intentas descargar datos sera de la anterior.

Solo es cuestion de aplicar un poco de logica algo asi:
Código PHP:
$resultado $a->Consulta"SELECt..." );
$resultado2 $a->Consulta"OtroSelect.." );

while( 
$row $resultado->fetchRow() ) {

}

while( 
$row2 $resultado2->fetchRow() ) {


Un ejemplo basico de una clase result seria:
Código PHP:
class Resultset {
      private 
$result null;
      public function 
__construct$resource ) {
            
$this->result $resource;
      }

      public function 
fetchRow() {
            return 
mysql_fetch_array$this->result );
      }

Me enredè....

Dime que paràmetro guardarìa $resultado y $resultado2?? La que tenga mysql_query(consulta)??

Es que segùn lo que me dices, asì lo tengo
Código PHP:
function consultar($query
    {
        
//aquí se realizan las consultas a la base de datos
        
$this->consulta=mysql_query($query);
    }    
    function 
obtenerDatos()
    {
        
//aquí se obtienen los datos de la consulta
        
$this->resultado=mysql_fetch_array($this->consulta);
        return 
$this->resultado;
    } 
Por lo que veo es que tù en tu consultar retornas un paràmetro, yo en el mìo no, pero lo "agarro" en obtenerDatos..., y yo retorno el resultado tal y como tù lo haces en fetchRow, no vendrìa siendo lo mismo??
__________________
Hay 10 tipos de personas, los que entienden binario y los que no. (Anónimo)
www.programandoweb.com
  #34 (permalink)  
Antiguo 13/08/2007, 17:05
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 8 meses
Puntos: 2135
Re: Pregunta de principiante...

No, ya que al hacer tu segunda llamada a Consulta sobreescribes el primer valor, velo asi:
Código PHP:
$a->Consulta"SELECT..." ); // Aqui internamente $this->consulta supongamos vale 1
$row $a->obtenerDatos(); // Aqui regresamos un row: mysql_fetch_array( 1 );
$a->Consulta"SELECT ..." ); // Aqui ahora $this->consulta vale 2 por ser una nueva consulta
$raw $a->obtenerDatos(); // Ahora obtenemos el otro row de la consulta con valor 2 
Mas abajo en tu codigo haces esto:
Código PHP:
while( $row $a->obtenerDatos() ) {
       
// imprimir bla bla pero tu esperas tener datos de tu primera consulta, sin embargo ya la consulta no es la 1 si no es la dos porque ya sobreescribiste el valor al realizar tu segundo query..

Con esto te das una idea de como en la misma clase se sobreescriben los valores, y el porque es necesario que la clase te retorne un objeto con el resultado.

Saludos.
  #35 (permalink)  
Antiguo 13/08/2007, 17:09
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 8 meses
Puntos: 2135
Re: Pregunta de principiante...

Mira para que te des una idea te dejo una clase que usaba anteriormente (ahora cambie por PDO)

Código PHP:
<?php
/**
 * Class GeckoDB
 * 
 * @package com.geckowd.utils;
 * @author Christopher Valderrama <[email protected]>
 * @copyright Copyright (c) 2005
 * @version $Id$v1.0$26 Oct 2005
 * @access public
 **/
class GeckoDB {
    var 
$_server;        // @var string Private variable that holds the MySQL Server
    
var $_user;        // @var string Private variable that holds the MySQL User
    
var $_pass;        // @var string Private variable that holds the MySQL Password
    
var $_db;        // @var string Private variable that hodls the MySQL Database
    
var $_dbLink;        // @var resource Private variable that holds the MySQL Resource of the connection
    
var $_totalQuerys;    // @var integer Private variable that holds the Total number of Querys sent
    
var $_error;        // @var array Private variable that hodls all of the debug/error information
    
    /**
     * GeckoDB::GeckoDB()
     * 
     * This is the class constructor, it needs a complete array or it will fail upon
     * connecting, the array must have the following info:
     * + servidor a string with the database server
     * + usuario a string with the database user
     * + password a string with the database password
     * + db a string with the database to select (if auto)
     * 
     * @param array $dsn_arr A complete array holding the DSN info
     * @return GeckoDB a new instance of the GeckoDB Class
     * @access public
     **/
    
function GeckoDB($server$user$pass$db) {
        
$this->_server         $server;
        
$this->_user         $user;
        
$this->_pass         $pass;
        
$this->_db            $db;
        
$this->_totalQuerys    0;
        
$this->_error         = array();
    }
    
    
/**
     * GeckoDB::Create()
     * 
     * Returns a static instance of this class
     * 
     * @return GeckoDB a new instance of the GeckoDB Class
     * @access public
     **/
    
function Create() {
        static 
$GeckoDBInstance;
        global 
$GeckoDBSettings;
        
        if( !isset( 
$GeckoDBSettings ) ) {
            
trigger_error"GeckoDBSettigns not set!, check your config!"E_USER_ERROR );
        }
        
        if( !isset( 
$GeckoDBInstance ) && !is_object$GeckoDBInstance ) ) {
            
$GeckoDBInstance = new GeckoDB($GeckoDBSettings['server'], $GeckoDBSettings['user'], $GeckoDBSettings['password'], $GeckoDBSettings['database'] );
            if( 
$GeckoDBSettings['auto_connect'] ) $GeckoDBInstance->Connect();
        }
        
        return 
$GeckoDBInstance;
    }
    
    
/**
     * GeckoDB::Connect()
     * 
     * This function attemps to connect to a MySQL Server must be called after the constructor
     * @see GeckoDB::GeckoDB()
     * @access public
     * @param string $db (optional) the database to connect if not specified in the $dsn_arr variable
     * @return boolean if true, means the connection was succesfull (will fail upon failure)
     **/
    
function Connect$db '' ) {
        
$this->_dbLink = @mysql_connect"$this->_server""$this->_user""$this->_pass" );
        if( 
is_resource$this->_dbLink ) ) {
            
$this->_debug"Succesfully Connected, Host: " mysql_get_host_info$this->_dbLink ) . ", MySQL Version: " mysql_get_server_info$this->_dbLink ) );
            
            
$db = ( empty( $db ) ? $this->_db $db );
            
            if( !
mysql_select_db"$db"$this->_dbLink ) ) {
                
$this->_fatalError"Can't select that Database" );
                return 
false;
            }
            
            
$this->_debug"Actual DB: $db" );
            return 
true;
        } else {
            
$this->_fatalError"Error can't connect: {$this->_server}" );
            return 
false;
        }
    }
    
    function 
changeDB$db ) {
        if( !
$this->Connected() ) {
            
$this->_fatalError"Can't Change Database, no Connection" );
            return 
false;
        }
        
        if( !
mysql_select_db$db$this->_dbLink ) ) {
            
$this->_fatalError"Can't select that Database" );
            return 
false;
        }
        
        
$this->_debug"Actual DB: $db" );
        return 
true;
    }
    
    
/**
     * GeckoDB::Connected()
     * 
     * This function will test if the MySQL connection is still alive (and will try to reconnect)
     * if it fails it will show a error and will stop script.
     * 
     * @return boolean will return true if is connected or will fail if it can't connect
     * @access public
     **/
    
function Connected$autoRenew false ) {
        if( !
is_resource$this->_dbLink) ) {
            if( 
$autoRenew && !@mysql_ping$this->_dbLink ) ) {
                
$this->_fatalError"Couldn't reconnect" );
            }
            return 
false;
        }
        return 
true;
    }
        
    
/**
     * GeckoDB::_debug()
     * 
     * This function saves a message with the correct TimeStamp in the $_error array.
     * 
     * @param string $msg the message to save
     * @access private
     * @return 
     **/
    
function _debug$msg ) {
        
$this->_error[] = $msg;
    }
    
    
/**
     * GeckoDB::_fatalError()
     * 
     * This function will display a error message and the mysql error number if a fatal
     * error is encountered.
     * 
     * It will also mail the error message and the class log, to the specified adress
     * (you need to define $GeckoDBErrorMail at some point before initializing the class)
     * 
     * @param string $msg the message to show upon failure
     * @access private
     * @return 
     **/
    
function _fatalError$msg ) {
        global 
$GeckoDBErrorMail;
        
        if( 
is_resource$this->_dbLink ) ) {
            
$errNo mysql_errno$this->_dbLink );
            
$errMsg mysql_error$this->_dbLink );
        } else {
            
$errNo mysql_errno();
            
$errMsg mysql_error();
        }
        
$this->_debug$msg " (errNo: $errNo) MySQL Message: $errMsg" );
        
        if( !empty( 
$GeckoDBErrorMail ) ) {
            
ini_set'sendmail_from'"geckodberror@" $_SERVER['SERVER_NAME'] );
            
$headers =  "From: geckodberror@{$_SERVER['SERVER_NAME']}\r\n" .
                        
"Reply-To: webmaster@{$_SERVER['SERVER_NAME']}\r\n" .
                        
"X-Mailer: GeckoDB Engine";
            
$subject "Database Error";
            
$toMail "There is a database error($errNo): $errMsg\n\n";
            
$toMail .= "additonal data:\n\n";
            
$toMail .= implode"\n"$this->_error );
            
            @
mail$GeckoDBErrorMail$subject$toMail$headers );        
        }
        
        
$fatalMsg "There appears to be a Database Error, please click <a href=\"javascript:history.go(-1);\">back</a> and try again<br><br>";
        
$fatalMsg.= "<hr>MySQL Info:<br><textarea rows=\"5\" cols=\"40\">$msg ($errNo): $errMsg</textarea>";
        
        die( 
$fatalMsg );
    }
    
    
/**
     * GeckoDB::getLog()
     * 
     * This function will return the log of all the functions called in the
     * class, and will join them by the glue parameter "\n" is the default, 
     * you can use for example "<br />".
     * 
     * @param string $glue the parameter to join 
     * @access public
     * @return string the log in a string form
     **/
    
function getLog$glue "\n" ) {
        return 
implode$glue$this->_error );
    }
    
    
/**
     * GeckoDB::ListDBs()
     * 
     * This function will list the Databases in the current connection, can be called after Connect
     * @see GeckoDB::Connect()
     * 
     * @access public
     * @return array a array fulled of the databases in the connection
     **/
    
function ListDBs() {
        if( !
$this->Connected() ) {
            return 
false;
        }
        
        
$dblist = @mysql_list_dbs$this->_dbLink );
        
$dbs = array();
        while( 
$d mysql_fetch_row$dblist ) ) {
            
$dbs[] = $d[0];
        }
        
$this->_debug"dbs listed" );
        
$this->_totalQuerys++;
        return 
$dbs;
    }
    
    
/**
     * GeckoDB::ListTables()
     * 
     * This function will return a array with all of the current tables
     * in the active Databases must be called after Connect
     * @see GeckoDB::Connect()
     * @access public
     * @return array the list of the tables in the current db
     **/
    
function ListTables() {
        if( !
$this->Connected() ) {
            return 
false;
        }
        
        
$query "SHOW TABLES FROM {$this->_db}";
        
$result = @mysql_query$query );
        if( !
$result $this->_fatalError"Error listing tables" );
        
        
$tables = array();
        while( 
$table mysql_fetch_row$result ) ) {
            
$tables[] = $table[0];
        }
        
        
$this->_debug"tables in {$this->_db} listed" );
        
$this->_totalQuerys++;
        return 
$tables;
    }

    
/**
     * GeckoDB::Query()
     * 
     * This function is the core of the class, it can send a MySQL Query
     * and if it fails it will display the error and possible mail it.
     * 
     * This function can return a new GeckoDBResult object or a boolean
     * true if the query was sent.
     * 
     * @see GeckoDBResult::GeckoDBResult()
     * @see GeckoDB::_fatalError()
     * @access public
     * @param string $query the query to send to MySQL
     * @return mixed this function can return a new Object or a boolean
     **/
    
function Query$query ) {
        if( !
$this->Connected() ) {
            return 
false;
        }
        
        if( !
class_exists"GeckoDBResult" ) ) {
            
$this->_fatalError"GeckoDBResult class not defined" );
            return 
false;
        }
        
        
$this->_totalQuerys++;
        
$result = @mysql_query$query$this->_dbLink );
        if( !
$result $this->_fatalError"Error in query $query" );
        
        
$this->_debug("Sent a query: $query");
        if( 
is_resource$result ) ) {
            
$rObj = new GeckoDBResult$query$result );
        } else {
            
$rObj $result;
        }
        
        return 
$rObj;
    }
    
    function 
parseQuery$query$data ) {
        for( 
$i 0$i count$data ); $i++ ) {
            
$data[$i] = $this->_escapeString$data[$i] );
        }
        
        
$newarray array_merge( array( $query ), $data );
        return 
call_user_func_array"sprintf"$newarray );
    }

    function 
AffectedRows() {
        if( !
$this->Connected() ) {
            return 
false;
        }
        
        return 
mysql_affected_rows$this->_dbLink );
    }
    
    
    function 
getTotalQuerys() {
        return 
$this->_totalQuerys;
    }

    
    function 
LastInsertID() {
        return 
mysql_insert_id$this->_dbLink );
    }
    
    
    function 
_escapeString$value ) {
        
        if( 
get_magic_quotes_gpc() ) {
            
$value stripslashes$value );
        }
        
        if( !
is_numeric$value ) ) {
            
$value mysql_real_escape_string$value$this->_dbLink );
        }
        
        
$this->_debug"escaped: $value" );
        
        return 
$value;
    }
    
    
    function 
Disconnect() {
        
$this->_debug"connection closed" );
        @
mysql_close$this->_dbLink );
    }
}
?>
  #36 (permalink)  
Antiguo 13/08/2007, 17:10
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 8 meses
Puntos: 2135
Re: Pregunta de principiante...

2da parte:
Código PHP:
<?php
/**
 * GeckoDBResult
 * 
 * @package com.geckowd.utils;
 * @author Christopher Valderrama <[email protected]>
 * @copyright Copyright (c) 2005
 * @version $Id$1.0$26 Oct 2005
 * @access private
 **/
class GeckoDBResult {
    var 
$_result// @var resource the resultset of the current MySQL result
    
var $_query// @var string the current query sent
    
var $rows// @var integer the number of rows (read only)
    
    /**
     * GeckoDBResult::GeckoDBResult()
     * 
     * Constructor, returns a new instance of GeckoDBResult
     * 
     * @param string $query
     * @param resource $result
     * @return GeckoDBResult a new instance of the class
     **/
    
function GeckoDBResult$query$result ) {
        
$this->_result     $result;
        
$this->_query     $query;
        
        
$this->rows mysql_num_rows$this->_result );
    }
    
    
/**
     * GeckoDBResult::getQuery()
     * 
     * This function will return the query of this class
     * 
     * @access public
     * @return string the query of this class
     **/
    
function getQuery() {
        return 
$this->_query;
    }
    
    
/**
     * GeckoDBResult::numRows()
     * 
     * This function will return the total number of records for this resultset
     * 
     * @access public
     * @return integer the number of rows for this resultset
     **/
    
function numRows() {
        return 
$this->rows;
    }

    
/**
     * GeckoDBResult::numFields()
     * 
     * This function return the number of fields for the current query
     * 
     * @access public
     * @return integer the number of fields
     **/
    
function numFields() {
        return 
mysql_num_fields$this->_result );
    }
    
    
/**
     * GeckoDBResult::fetchField()
     * 
     * This function will return the name of the field specified by $fieldNumber
     * 
     * @access public
     * @param integer $fieldNumber
     * @return string the name of the field
     **/
    
function fetchField$fieldNumber ) {
        return 
mysql_field_name$this->_result$fieldNumber );
    }

    
/**
     * GeckoDBResult::fetchRow()
     * 
     * This function will return the current row of the query or false when no more rows are left
     * 
     * @access public
     * @param integer $fetchMode
     * @param boolean $stripResult
     * @return mixed the current result of the active row or false when no more records are found
     **/
    
function fetchRow$fetchMode MYSQL_BOTH$stripResult true ) {
        
$row mysql_fetch_array$this->_result$fetchMode );
        if( 
is_array$row ) && ( $stripResult ) ) {
            
$row array_map"stripslashes"$row );
        }
        
        return 
$row;
    }
    
    
/**
     * GeckoDBResult::fetchAll()
     * 
     * This function will fetch ALL rows of a resultset and return a array with each element of the array
     * equal to a row of the result
     * 
     * @access public
     * @param integer $fetchMode
     * @param boolean $stripResult
     * @return mixed the current result of the active row or false when no more records are found
     **/
    
function fetchAll$fetchMode MYSQL_BOTH$stripResult true ) {
        
$rows = array();
        
        while( 
$row $this->fetchRow$fetchMode$stripResult ) ) $rows[] = $row;
        
        return 
$rows;
    }
    
    
/**
     * GeckoDBResult::fetchColumn()
     * 
     * This function will fetch the first value of the query, but will itirate all of the values to make a column or list
     * 
     * @access public
     * @param integer $fetchMode
     * @param boolean $stripResult
     * @return mixed the current result of the active row or false when no more records are found
     **/
    
function fetchColumn() {
        
$column = array();
        
        while( 
$value $this->fetchFirst() ) $column[] = $value;
        
        return 
$column;
    }
    
    
/**
     * GeckoDBResult::fetchFirst()
     * 
     * This function will return the first value of a query
     * 
     * @access public
     * @return mixed The value of the query or false on no rows
     **/
    
function fetchFirst() {
        
$result false;
        
$row $this->fetchRowMYSQL_NUMtrue );
        if( 
is_array$row ) ) {
            
$result $row[0];
        }
        
        return 
$result;
    }
    
    
/**
     * GeckoDBResult::seekRow()
     * 
     * This function will seek to a specified result in the active resultset
     * 
     * @access public
     * @param integer $rowNumber
     * @return boolean will attemp to seek to a result on the active resultset
     **/
    
function seekRow$rowNumber ) {
        return @
mysql_data_seek$this->_result$rowNumber );
    }

    
/**
     * GeckoDBResult::fetchLastRow()
     * 
     * This function will return the last row on the active resultset
     * 
     * @access public
     * @param integer $fetchMode
     * @param boolean $stripResult
     * @return array the last result of the active resultset
     **/
    
function fetchLastRow$fetchMode MYSQL_BOTH$stripResult true ) {
        
$this->seekRow$this->numRows() - );
        return 
$this->fetchRow$fetchMode$stripResult );
    }
    
    
/**
     * GeckoDBResult::clearResult()
     * 
     * This function will clear the current resultset
     * 
     * @return boolean if the result could be cleared
     **/
    
function clearResult() {
        if( 
is_resource$this->_result ) ) {
            return @
mysql_free_result$this->_result );
        }
    }
    function 
delete() {
        return 
$this->clearResult();
    }
}
?>
Le quite un poco de documentación porque esta muy larga y no me dejaba publicarla jeje

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 14:12.