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

Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Estas en el tema de Duda con clase mysql, saber si se ejecuta 2 veces la consulta en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Buenas, Tengo una pequeña duda, Si tengo esta clase mysql class-mysql.php @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código PHP: Ver original <?php   class DataBase {       ...

  #1 (permalink)  
Antiguo 31/03/2010, 11:35
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Buenas,

Tengo una pequeña duda,

Si tengo esta clase mysql

class-mysql.php
Código PHP:
Ver original
  1. <?php
  2.  
  3. class DataBase {
  4.  
  5.     private $conexion;
  6.     private $resource;
  7.     private $sql;
  8.     public static $queries;
  9.     private static $_singleton;
  10.  
  11.     public static function getInstance($servidor, $user, $password, $db){
  12.         if (is_null (self::$_singleton)) {
  13.             self::$_singleton = new DataBase($servidor, $user, $password, $db);
  14.         }
  15.         return self::$_singleton;
  16.     }
  17.  
  18.     private function __construct($servidor, $user, $password, $db){
  19.         $this->conexion = @mysql_connect($servidor, $user, $password);
  20.         mysql_select_db($db, $this->conexion);
  21.         $this->queries = 0;
  22.         $this->resource = null;
  23.     }
  24.  
  25.     public function execute(){
  26.         if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  27.             return null;
  28.         }
  29.         $this->queries++;
  30.         return $this->resource;
  31.     }
  32.  
  33.     public function alter(){
  34.         if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  35.             return false;
  36.         }
  37.         return true;
  38.     }
  39.  
  40.     public function loadObjectList(){
  41.         if (!($cur = $this->execute())){
  42.             return null;
  43.         }
  44.         $array = array();
  45.         while ($row = @mysql_fetch_object($cur)){
  46.             $array[] = $row;
  47.         }
  48.         return $array;
  49.     }
  50.  
  51.     public function setQuery($sql){
  52.         if(empty($sql)){
  53.             return false;
  54.         }
  55.         $this->sql = $sql;
  56.         return true;
  57.     }
  58.  
  59.     public function freeResults(){
  60.         @mysql_free_result($this->resource);
  61.         return true;
  62.     }
  63.  
  64.     public function loadObject(){
  65.         if ($cur = $this->execute()){
  66.             if ($object = mysql_fetch_object($cur)){
  67.                 @mysql_free_result($cur);
  68.                 return $object;
  69.             }
  70.             else {
  71.                 return null;
  72.             }
  73.         }
  74.         else {
  75.             return false;
  76.         }
  77.     }
  78.    
  79.     //Numero de columnas   
  80.     function num_rows(){
  81.         return @mysql_num_rows($this->execute());
  82.     }
  83.    
  84.     function __destruct(){
  85.         @mysql_free_result($this->resource);
  86.         @mysql_close($this->conexion);
  87.     }
  88. }
  89. ?>

Y lanzo este script de prueba

prueba.php
Código PHP:
Ver original
  1. <?php
  2. include('class-mysql.php');
  3.  
  4. // Hacemos la conexión
  5. $db = DataBase::getInstance('localhost','root','pass','hmgroupcat');
  6.  
  7. // Supongamos que tenemos una tabla de usuarios
  8. // Hacemos la consulta:
  9. $db->setQuery("SELECT ID,post_date,post_content FROM wp_posts");
  10.  
  11. // La ejecutamos y al mismo tiempo obtenemos un arreglo de objetos
  12. // con los campos especificados en la consulta como propiedades.
  13. $datos = $db->loadObjectList();
  14. echo $db->num_rows();
  15.  
  16. echo "<pre>";
  17. print_r($datos);
  18. echo "</pre>";
  19. // Los imprimimos directamente en pantalla...
  20. foreach($datos as $campo){
  21.     echo 'ID: '.$campo->ID;
  22.     echo 'Nombre: '.$campo->post_name;
  23.     echo 'Grupo: '.$campo->post_status;
  24.     echo '<br />';
  25. }
  26.  
  27. ?>

Mi pregunta es si en la linea del
echo $db->num_rows();

¿Se vuelve a lanzar la consulta a la base de datos? de ser así, no es óptimo que la lance dos veces, no?

Se como solucionarlo si hago un count($datos) me dirá cuantas filas me arrojó la consulta SQL, pero si quisiera sacar ese número con la clase mysql sin tener que hacer de nuevo la consulta, ¿habría alguna forma? :S

Muchas gracias de antemano!
  #2 (permalink)  
Antiguo 31/03/2010, 11:45
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

A tu pregunta, sí ya que tu método num_rows manda a llamar a $this->execute(); Lo que tendrías que hacer es checar dentro de tu método execute() si ya existe un $this->resource, y en dado caso que exista usar ese en lugar de volverlo a lanzar.

Saludos.
  #3 (permalink)  
Antiguo 31/03/2010, 12:54
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
A tu pregunta, sí ya que tu método num_rows manda a llamar a $this->execute(); Lo que tendrías que hacer es checar dentro de tu método execute() si ya existe un $this->resource, y en dado caso que exista usar ese en lugar de volverlo a lanzar.

Saludos.
Es decir, que debería quedar así?

Código PHP:
Ver original
  1. public function execute(){
  2.         if (!$this->resource){
  3.             if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  4.                 return null;
  5.             }
  6.         }
  7.         $this->queries++;
  8.         return $this->resource;
  9.     }

Qué es lo que se guarda en el $this->resource? el resultado del mysql_query?

Si es así, porque no utilizar directamente en la función del número de columnas?
Código PHP:
Ver original
  1. function num_rows(){
  2.         return @mysql_num_rows($this->resource);
  3.     }

Muchas gracias de antemano!
  #4 (permalink)  
Antiguo 31/03/2010, 13:43
Avatar de eulloa  
Fecha de Ingreso: octubre-2007
Ubicación: Donde caiga la noche, si mi hijo me deja
Mensajes: 691
Antigüedad: 17 años
Puntos: 5
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Según como lo tienes y creo entender, en el $this->resource lo que guardas es eso, el resource de la query q estás haciendo.
Si quieres más info sobre el resource type
Ahora lo que tendrías que hacer es más como isset($this->resource)
  #5 (permalink)  
Antiguo 31/03/2010, 14:21
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

O usar mejor is_resource y en efecto es mejor si usas directamente "return mysql_num_rows($this->resource);".

PD. no es tan recomendable que uses @ es mejor que tengas una mejor forma de controlar tus errores que solamente suprimirlos.

Saludos.
  #6 (permalink)  
Antiguo 31/03/2010, 14:35
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
O usar mejor is_resource y en efecto es mejor si usas directamente "return mysql_num_rows($this->resource);".

PD. no es tan recomendable que uses @ es mejor que tengas una mejor forma de controlar tus errores que solamente suprimirlos.

Saludos.
He entendido bien...?
Para ese caso del mysql_num_rows no haría falta usar el is_resource y es mejor utilizar directamente el return mysql_num_rows($this->resource);

Pero para este caso si que lo ideal sería que quedase así?

Código PHP:
Ver original
  1. private function __construct($servidor, $user, $password, $db){
  2.         $this->conexion = mysql_connect($servidor, $user, $password);
  3.         if (!is_resource($this->conexion)) {
  4.             die('Can\'t connect : ' . mysql_error());
  5.         }
  6.         mysql_select_db($db, $this->conexion);
  7.         $this->queries = 0;
  8.         $this->resource = null;
  9.     }

Y en lugar de

Código PHP:
Ver original
  1. public function execute(){
  2.         if (!$this->resource){
  3.             if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  4.                 return null;
  5.             }
  6.         }
  7.         $this->queries++;
  8.         return $this->resource;
  9.     }

Quedaría así?

Código PHP:
Ver original
  1. public function execute(){
  2.         if (!is_resource($this->resource)) {
  3.             if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  4.                 return null;
  5.             }
  6.         }
  7.         $this->queries++;
  8.         return $this->resource;
  9.     }

Muchas gracias de antemano
  #7 (permalink)  
Antiguo 31/03/2010, 14:46
Avatar de eulloa  
Fecha de Ingreso: octubre-2007
Ubicación: Donde caiga la noche, si mi hijo me deja
Mensajes: 691
Antigüedad: 17 años
Puntos: 5
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Nop, se hablan de dos cosas diferentes
Código PHP:
Ver original
  1. public function execute(){
  2.         if (!is_resource($this->resource)) {
  3.                 return null;
  4.         }
  5.         $this->queries++;
  6.         return $this->resource;
  7.     }
  8.  
  9. function num_rows(){
  10.         return mysql_num_rows($this->resource); //SIN LA @
  11.     }
  #8 (permalink)  
Antiguo 31/03/2010, 16:18
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por eulloa Ver Mensaje
Nop, se hablan de dos cosas diferentes
Código PHP:
Ver original
  1. public function execute(){
  2.         if (!is_resource($this->resource)) {
  3.                 return null;
  4.         }
  5.         $this->queries++;
  6.         return $this->resource;
  7.     }
  8.  
  9. function num_rows(){
  10.         return mysql_num_rows($this->resource); //SIN LA @
  11.     }
Buenas,

El que código que has puesto eulloa falta la consulta no? :S

Código PHP:
Ver original
  1. public function execute(){
  2.         if (!is_resource($this->resource)) {
  3.             if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  4.                 return null;
  5.             }
  6.         }
  7.         $this->queries++;
  8.         return $this->resource;
  9.     }
  10.  
  11. private function __construct($servidor, $user, $password, $db){
  12.         $this->conexion = mysql_connect($servidor, $user, $password);
  13.         if (!is_resource($this->conexion)) {
  14.             die('Can\'t connect : ' . mysql_error());
  15.         }
  16.         mysql_select_db($db, $this->conexion);
  17.         $this->queries = 0;
  18.         $this->resource = null;
  19.     }

Correcto?
  #9 (permalink)  
Antiguo 31/03/2010, 16:42
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

En efecto faltaría ejecutar la consulta. Es siempre no recomendable usar @ a menos que estes ya manejando el error, si no solo se silencia el error y no puedes ver que pasa.

Saludos.
  #10 (permalink)  
Antiguo 01/04/2010, 02:01
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
En efecto faltaría ejecutar la consulta. Es siempre no recomendable usar @ a menos que estes ya manejando el error, si no solo se silencia el error y no puedes ver que pasa.

Saludos.
Si quito la @ y muestro el mensaje de error

Código PHP:
Ver original
  1. $this->conexion = mysql_connect($servidor, $user, $password);
  2.         if (!is_resource($this->conexion)) {
  3.             die('No se pudo conectar a la base de datos: ' . mysql_error());
  4.         }

No se pudo conectar a la base de datos: Access denied for user 'roo4t'@'localhost' (using password: YES)

No estoy dando información al visitante del usuario de la base de datos?

Y lo mismo a la hora de un fallo al seleccionar la base de datos

Código PHP:
Ver original
  1. $db_selected = mysql_select_db($db, $this->conexion);
  2.         if (!$db_selected) {
  3.             die ('No se pudo seleccionar la base de datos: ' . mysql_error());
  4.         }

No se pudo seleccionar la base de datos: Unknown database 'hmgr4oupcat'


¿Debería eliminar el mysql_error() del final de cada die, para hacerlo más seguro, no?

Muchas gracias de antemano
  #11 (permalink)  
Antiguo 01/04/2010, 06:31
Avatar de eulloa  
Fecha de Ingreso: octubre-2007
Ubicación: Donde caiga la noche, si mi hijo me deja
Mensajes: 691
Antigüedad: 17 años
Puntos: 5
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

NO, lo que deberías hacer es solventar los errores. De todas formas estás en fase de desarrollo y ver los errores es importante es esta fase.
Luego, lo que te ha sugerido GatorV, es manejar los errores tu mismo. Puedes consultar excepciones
No te preocupes tanto por estas medidas de seguridad al principio. Más tarde lo harás
  #12 (permalink)  
Antiguo 01/04/2010, 06:58
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por eulloa Ver Mensaje
NO, lo que deberías hacer es solventar los errores. De todas formas estás en fase de desarrollo y ver los errores es importante es esta fase.
Hola eulloa, no estoy en fase de desarrollo de la aplicación, sino más bien en fase de retoques de la clase mysql.

Los errores de arriba son provocados a consciencia, para que indicar eso, que con mysql_error() aparece información que el visitante podría "utilizar"
  #13 (permalink)  
Antiguo 01/04/2010, 07:05
Avatar de eulloa  
Fecha de Ingreso: octubre-2007
Ubicación: Donde caiga la noche, si mi hijo me deja
Mensajes: 691
Antigüedad: 17 años
Puntos: 5
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por neodani Ver Mensaje
Hola eulloa, no estoy en fase de desarrollo de la aplicación, sino más bien en fase de retoques de la clase mysql.
Retoques, desarrollo, en fin que no está oficialmente en línea ¿no?. Estás "probando", luego: fase de desarrollo

Cita:
Iniciado por neodani Ver Mensaje
Los errores de arriba son provocados a consciencia
Provocados a conciencia (fase de desarrollo)

Cita:
Iniciado por neodani Ver Mensaje
para que indicar eso, que con mysql_error() aparece información que el visitante podría "utilizar"
Entonces lo que te ha sugerido GatorV, maneja tu mismo los errores. Visita el link q te dejé, es del mismo manual
  #14 (permalink)  
Antiguo 01/04/2010, 08:23
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

En efecto es para cuando estas en fase de desarrollo en producción no debes de mostrar esos errores si no solamente "un error ocurrió", y manejar log de errores o algo por el estilo (usar excepciones es una muy buena forma).

Saludos.
  #15 (permalink)  
Antiguo 05/04/2010, 12:11
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Muchas gracias a ambos por las aclaraciones

Estoy intentando entender toda la clase de pies a cabeza, he añadido nuevos métodos y la estoy "documentando", pero hay algunas funciones que no acabo de entender por completo.

A continuación la clase al completo y un ejemplo de implementación.

class-mysql.php
Código PHP:
Ver original
  1. <?php
  2.  
  3. class DataBase {
  4.  
  5.     private $conexion;
  6.     private $resource;
  7.     private $sql;
  8.     public static $queries;
  9.     private static $_singleton;
  10.  
  11.     public static function getInstance($servidor, $user, $password, $db){
  12.     // Implementación del patrón SINGLETON para no repetir instancias
  13.         if (is_null (self::$_singleton)) {
  14.             self::$_singleton = new DataBase($servidor, $user, $password, $db);
  15.         }
  16.         return self::$_singleton;
  17.     }
  18.  
  19.     private function __construct($servidor, $user, $password, $db){
  20.     // Conecta al servidor
  21.         $this->conexion = mysql_connect($servidor, $user, $password);
  22.         if (!is_resource($this->conexion)) {
  23.             die('No se pudo conectar a la base de datos: ' . mysql_error());
  24.         }
  25.      // Selecciona la base de datos
  26.         $db_selected = mysql_select_db($db, $this->conexion);
  27.         if (!$db_selected) {
  28.             die ('No se pudo seleccionar la base de datos: ' . mysql_error());
  29.         }
  30.         $this->queries = 0;
  31.         $this->resource = null;
  32.     }
  33.  
  34.     public function execute(){
  35.         if (!is_resource($this->resource)) {
  36.             if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  37.                 return null;
  38.             }
  39.         }
  40.         $this->queries++;
  41.         return $this->resource;
  42.     }
  43.  
  44.     public function alter(){
  45.         if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  46.             return false;
  47.         }
  48.         return true;
  49.     }
  50.  
  51.     public function getArrayResult(){
  52.     // Devuelve un array asociativo de la consulta (por nombres de campo en vez de por indice de campo)
  53.         if (!($cur = $this->execute())){
  54.             return null;
  55.         }
  56.         $array = array();
  57.         while ($row = @mysql_fetch_object($cur)){
  58.             $array[] = $row;
  59.         }
  60.         return $array;
  61.     }
  62.    
  63.     public function setQuery($sql){
  64.     // Carga la consulta SQL
  65.         if(empty($sql)){
  66.             return false;
  67.         }
  68.         $this->sql = $sql;
  69.         return true;
  70.     }
  71.  
  72.     public function freeResults(){
  73.         // Libera el resultado de la memoria y continua con el script
  74.         mysql_free_result($this->resource);
  75.         return true;
  76.     }
  77.  
  78.     public function loadObject(){
  79.         if ($cur = $this->execute()){
  80.             if ($object = mysql_fetch_object($cur)){
  81.                 mysql_free_result($cur);
  82.                 return $object;
  83.             }
  84.             else {
  85.                 return null;
  86.             }
  87.         }
  88.         else {
  89.             return false;
  90.         }
  91.     }
  92.    
  93.     public function getNumFilas(){
  94.         // Devuelve el numero total de filas (horizontal) de la consulta
  95.         return mysql_num_rows($this->resource);
  96.     }
  97.     function getNumColumnas(){
  98.         // Devuelve el numero total de columnas (vertical) de la consulta
  99.         return mysql_num_fields($this->resource);
  100.     }
  101.     public function getTotalConsultas(){
  102.         // Devuelve el numero total de consultas realizadas
  103.         return $this->queries;  
  104.     }
  105.    
  106.     public function depura($data){
  107.     // Funcion para evitar el SQL INJECTION
  108.         // Elimina los espacios en blanco
  109.         $data = trim($data);
  110.         // Aplicará stripslashes si está habilitado magic_quotes_gpc
  111.         if(get_magic_quotes_gpc())
  112.         {
  113.             $data = stripslashes($data);
  114.         }
  115.         // Hace falta una conexión a mySQL para usar esta funcion
  116.         $data = mysql_real_escape_string($data);
  117.         return $data;
  118.     }
  119.  
  120.  
  121.     public function getUltimoID(){
  122.         if(!($this->resource = mysql_query(mysql_insert_id(), $this->conexion))){
  123.             return false;
  124.         }
  125.         $this->queries++;
  126.         return $this->resource;
  127.     }
  128.    
  129.     public function fetch_array(){  
  130.         return mysql_fetch_array($this->resource);  
  131.     }
  132.    
  133.     function __destruct(){
  134.         // Libera el resultado de la memoria y cierra la conexión
  135.         mysql_free_result($this->resource);
  136.         mysql_close($this->conexion);
  137.     }
  138. }
  139. ?>

Implementación
Código PHP:
Ver original
  1. <?php
  2. include('class-mysql.php');
  3.  
  4. // Hacemos la conexión
  5. $db = DataBase::getInstance('localhost','root','password','hmgroupcat');
  6.  
  7. // Prueba de valores
  8. $valor1=1;
  9. $valor2='2009-10-06 19:03:49';
  10.  
  11. $valor1=$db->depura($valor1);
  12. $valor2=$db->depura($valor2);
  13.  
  14. // Hacemos la consulta segura:
  15. $query = sprintf("SELECT ID,post_date,post_content FROM wp_posts WHERE ID='%s' OR post_date='%s'",
  16.     $valor1, $valor2);
  17. $db->setQuery($query);
  18.  
  19. // La ejecutamos y al mismo tiempo obtenemos un arreglo de objetos
  20. // con los campos especificados en la consulta como propiedades.
  21. $datos = $db->getArrayResult();
  22.  
  23. //$datos = $db->fetch_array();
  24. //echo $db->getUltimoID();
  25.  
  26. // Otro ejemplo de depuración de datos de entrada
  27. $_POST['username']='n-1"\/%aDan';
  28. $_POST['password']='23/""\1235a*!';
  29. echo $username = $db->depura($_POST['username']);
  30. echo "<br/>";
  31. echo $password = $db->depura($_POST['password']);
  32.  
  33. echo $db->getNumFilas();
  34. echo "<br/>";
  35. echo $db->getNumColumnas();
  36. echo "<br/>";
  37. echo $db->getTotalConsultas();
  38.  
  39. echo "<pre>";
  40. print_r($datos);
  41. echo "</pre>";
  42.  
  43. // Los imprimimos directamente en pantalla...
  44. /*foreach($datos as $campo){
  45.     echo 'ID: '.$campo->ID;
  46.     echo 'Nombre: '.$campo->post_name;
  47.     echo 'Grupo: '.$campo->post_status;
  48.     echo '<br />';
  49. }
  50. */
  51. ?>

Y ahora las TRES funciones que me gustaría que me explicarais que es lo que hacen...

Código PHP:
Ver original
  1. public function execute(){
  2.         if (!is_resource($this->resource)) {
  3.             if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  4.                 return null;
  5.             }
  6.         }
  7.         $this->queries++;
  8.         return $this->resource;
  9.     }
  10.  
  11.     public function alter(){
  12.         if(!($this->resource = mysql_query($this->sql, $this->conexion))){
  13.             return false;
  14.         }
  15.         return true;
  16.     }
  17. public function loadObject(){
  18.         if ($cur = $this->execute()){
  19.             if ($object = mysql_fetch_object($cur)){
  20.                 mysql_free_result($cur);
  21.                 return $object;
  22.             }
  23.             else {
  24.                 return null;
  25.             }
  26.         }
  27.         else {
  28.             return false;
  29.         }
  30.     }

Esta no he conseguido que funcione:

Código PHP:
Ver original
  1. public function getUltimoID(){
  2.         if(!($this->resource = mysql_query(mysql_insert_id(), $this->conexion))){
  3.             return false;
  4.         }
  5.         $this->queries++;
  6.         return $this->resource;
  7.     }

Y esta de aquí function getArrayResult() pensaba que se podría hacer de la siguiente manera pero no funciona, es muy diferente?

Código PHP:
Ver original
  1. public function fetch_array(){  
  2.         return mysql_fetch_array($this->resource);  
  3.     }

Muchas gracias de antemano!
  #16 (permalink)  
Antiguo 05/04/2010, 14:08
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Si lees el manual de PHP, solamente debes de usar mysql_insert_id() con el parámetro a la conexión, no la debes de pasar a mysql_query, o sea que tu función quedaría así:
Código PHP:
Ver original
  1. public function getUltimoID()
  2. {
  3.     $ultimoId = mysql_insert_id($this->conexion);
  4.     return $ultimoId;
  5. }

Tu función fetch_array lo que hace es regresar un array de tu ultimo resultado.

Saludos.
  #17 (permalink)  
Antiguo 05/04/2010, 14:41
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
Si lees el manual de PHP, solamente debes de usar mysql_insert_id() con el parámetro a la conexión, no la debes de pasar a mysql_query, o sea que tu función quedaría así:
Código PHP:
Ver original
  1. public function getUltimoID()
  2. {
  3.     $ultimoId = mysql_insert_id($this->conexion);
  4.     return $ultimoId;
  5. }
Lo ejecuté, y me mostró 0 como ultimoId

No debería mostrar el último ID autonumerico del último valor?

Código PHP:
Ver original
  1. // Hacemos la consulta segura:
  2. $query = sprintf("SELECT ID,post_date,post_content FROM wp_posts WHERE ID='%s' OR post_date='%s'",
  3.     $valor1, $valor2);
  4. $db->setQuery($query);
  5.  
  6. // La ejecutamos y al mismo tiempo obtenemos un arreglo de objetos
  7. // con los campos especificados en la consulta como propiedades.
  8. $datos = $db->getArrayResult();
  9. //echo $db->countAffectedRows();
  10. //$datos2 = $db->fetchAll();
  11. echo $db->getUltimoID();


Cita:
Iniciado por GatorV Ver Mensaje
Tu función fetch_array lo que hace es regresar un array de tu ultimo resultado.

Saludos.
Si la consulta me devuelve 10 filas solo mostrará la última fila en formato array, correcto?

Entonces esta función debería mostrar todas las filas en el array $rows no?

Código PHP:
Ver original
  1. public function fetchAll()
  2.     {
  3.           $rows = array();      
  4.           while ($row = mysql_fetch_array( $this->resource, MYSQL_ASSOC )) {
  5.               array_push($rows, $row);
  6.           }
  7.           return $rows;
  8.     }

Cuando lo ejecuto, me da error en la linea:
while ($row = mysql_fetch_array( $this->resource, MYSQL_ASSOC )) {


Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\AppServ\www\00-laboratorio_test\secciones\mysql\clase_mysql_1\cla ss-mysql.php on line 142


Por qué los argumentos no son correctos, si segun el manual son
( resource $result [, int $result_type = MYSQL_BOTH ] )

La siguiente pregunta que tengo es, que diferencia habría en conseguir hacerlo de la manera anterior o esta de aquí.

Código PHP:
Ver original
  1. public function getArrayResult(){
  2.     // Devuelve un array asociativo de la consulta (por nombres de campo en vez de por indice de campo)
  3.         if (!($cur = $this->execute())){
  4.             return null;
  5.         }
  6.         $array = array();
  7.         while ($row = @mysql_fetch_object($cur)){
  8.             $array[] = $row;
  9.         }
  10.         return $array;
  11.     }

Muchas gracias de antemano!
  #18 (permalink)  
Antiguo 05/04/2010, 16:16
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Te devuelve 0 ya que necesita ser llamado después de llamar a un INSERT() o un Stored Procedure que llame a un INSERT().

Del otro problema te lo muestra ya que $this->resource no es un recurso valido, prueba imprimir antes el valor de mysql_error() para que veas si tu consulta fallo.

Saludos.
  #19 (permalink)  
Antiguo 05/04/2010, 17:27
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
Te devuelve 0 ya que necesita ser llamado después de llamar a un INSERT() o un Stored Procedure que llame a un INSERT().

Del otro problema te lo muestra ya que $this->resource no es un recurso valido, prueba imprimir antes el valor de mysql_error() para que veas si tu consulta fallo.

Saludos.
Me diste la clave :D

Faltaba ejecutarlo, ahora funciona

Código PHP:
Ver original
  1. public function fetchAll()
  2.     {
  3.         if (!($cur = $this->execute())){
  4.             return null;
  5.         }
  6.         $rows = array();      
  7.         while ($row = mysql_fetch_array( $this->resource, MYSQL_ASSOC )) {
  8.             array_push($rows, $row);
  9.         }
  10.         return $rows;
  11.     }

Esta linea de aquí lo que hace es intentar ejecutar la consulta, si da problemas retornará null no?

Código PHP:
Ver original
  1. if (!($cur = $this->execute())){
  2.   return null;
  3. }

Otra pregunta,

¿Por qué cuando ejecuto los dos métodos a la vez, solo me muestra datos en el que ejecuto primero, en este caso $datos1 contiene información y $datos2 está vacio...?

Código PHP:
Ver original
  1. // Hacemos la consulta segura:
  2. $query = sprintf("SELECT ID,post_date,post_content FROM wp_posts WHERE ID='%s' OR post_date='%s'",
  3.     $valor1, $valor2);
  4.    
  5. $db->setQuery($query);
  6.  
  7. $datos1 = $db->getArrayResult();
  8. $datos2 = $db->fetchAll();
  9.  
  10. echo "<pre>";
  11. print_r($datos1);
  12. echo "</pre>";
  13. echo "<pre>";
  14. print_r($datos2);
  15. echo "</pre>";

Muchas gracias de antemano!
  #20 (permalink)  
Antiguo 05/04/2010, 20:27
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Eso es porque tu clase esta mal diseñada desde un principio y solo funciona para 1 sola consulta, si quieres ver una implementación múltiple te recomiendo leer como funciona PDO que precisamente separa su clase en PDO y PDOStatment, o Zend_Db que tiene Zend_Db_Adapter y Zend_Db_Statement.

Saludos.
  #21 (permalink)  
Antiguo 06/04/2010, 02:13
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
Eso es porque tu clase esta mal diseñada desde un principio y solo funciona para 1 sola consulta, si quieres ver una implementación múltiple te recomiendo leer como funciona PDO que precisamente separa su clase en PDO y PDOStatment, o Zend_Db que tiene Zend_Db_Adapter y Zend_Db_Statement.

Saludos.
Me dejas a cuadros O_o! tan mal está que no se puede retocar la parte "errónea"??

Me recomiendas que use en vez de mi clase, la clase PDO?

Saludos y gracias
  #22 (permalink)  
Antiguo 06/04/2010, 08:19
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Claro es mucho más recomendado usar PDO, por muchas razones, la primera, que es nativa (programada en C), otra es que es múltiple, puedes usar muchas bases de datos (mysql, mssql, sqlite, oracle, postgresql, odbc).

Otra es porque tiene un diseño mucho más abstracto, que te permite mantener más limpio tu implementación.

Para "arreglar" tu clase, debes de partirla en 2, una que sea el Connection Manager, y otro el Result Manager, es decir, una clase se encarga de manejar lo que es la conexión al servidor, enviar querys/etc. Tu otra clase se encarga de manejar un resultset de mysql, o sea, descargar resultados, número de filas, etc.

Esto es para que puedas tener una implementación más limpia, por ejemplo:
Código PHP:
Ver original
  1. $db  = Database(/** .. **/);
  2. //...
  3. $result1 = $db->query(/** query **/);
  4. $result2 = $db->query(/** query **/);
  5. while ($row = $result1->fetchRow()) {
  6.        // $row
  7. }
  8. while ($row = $result2->fetchRow()) {
  9.        // $row
  10. }

Saludos.
  #23 (permalink)  
Antiguo 10/04/2010, 22:46
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
De acuerdo Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
Si lees el manual de PHP, solamente debes de usar mysql_insert_id() con el parámetro a la conexión, no la debes de pasar a mysql_query, o sea que tu función quedaría así:
Código PHP:
Ver original
  1. public function getUltimoID()
  2. {
  3.     $ultimoId = mysql_insert_id($this->conexion);
  4.     return $ultimoId;
  5. }

Tu función fetch_array lo que hace es regresar un array de tu ultimo resultado.

Saludos.
GatorV distes en el punto clave.

En este caso no seria necesario pasarle $this->conexion como argumento, ya que es un parámetro opcional que de no ser especificado el método asume la ultima conexión abierta, la cual siempre será la misma porque la clase utiliza el patrón Singleton.

Código PHP:
Ver original
  1. int mysql_insert_id  ([  resource $link_identifier  ] )

Código PHP:
Ver original
  1. public function getUltimoID()
  2. {
  3.   $ultimoId = mysql_insert_id();
  4.   return $ultimoId;
  5. }

En resumen menos código más claridad.

PDO es más recomendable.

Última edición por atrianaster; 10/04/2010 a las 23:07
  #24 (permalink)  
Antiguo 11/04/2010, 21:09
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

@atrianaster

De hecho no, precisamente es el problema, su clase simplemente es un "wrapper" a unas funciones de MySQL y no le va a brindar completamente lo que necesita.

Aunque te "ahorres" el link, es recomendable que lo ponga, ya que de hecho no es recomendable el uso de Singleton para clases del tipo conexiones a DB, ya que limitan el poder usar tu clase más de una vez en una sola ejecución.
  #25 (permalink)  
Antiguo 12/04/2010, 17:28
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
ya que limitan el poder usar tu clase más de una vez en una sola ejecución.
El patrón de diseño"Singleton" está diseñado para restringir la creación de objetos pertenecientes a una clase.

Esta clase DataBase hace uso de este patrón, donde en el constructor abre la conexión a la base de datos MySQL utilizando la librería de funciones php_mysql.dll.

No se limita usar la clase, la clase la puedes usar cuantas veces quieras, así como invocar todos sus métodos indefinidamente una vez teniendo una instancia de la misma.
Lo que si se limita es la conexión a la base de datos que siempre será la misma, es decir cuando invocas al método getInstance este devuelve un enlace identificativo el cual será reutilizado una y otra vez.

Ventas:

1.) Que nuestra aplicación web ahorre recursos del servidor.
2.) Tenemos bien controlado la creación de objetos, al no permitir que nuestra aplicación tenga innumerable y descontroladas conexiones innecesarias abiertas a una misma base de datos.

Cita:
Iniciado por GatorV Ver Mensaje
ya que de hecho no es recomendable el uso de Singleton para clases del tipo conexiones a DB
No entiendo porque planteas esto.

Atento a tus comentarios.
Saludos y mis respetos como desarrollador.

Última edición por atrianaster; 12/04/2010 a las 17:35
  #26 (permalink)  
Antiguo 12/04/2010, 20:56
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Lo que pasa es un problema clave, que pasa cuando quieres trabajar en dos bases de datos diferentes en el mismo archivo?, es ahi cuando se ve una deficiencia de usar Singleton para clases que sean conexiones.

Si bien como dices:
Cita:
Iniciado por atrianaster Ver Mensaje
Ventas:

1.) Que nuestra aplicación web ahorre recursos del servidor.
2.) Tenemos bien controlado la creación de objetos, al no permitir que nuestra aplicación tenga innumerable y descontroladas conexiones innecesarias abiertas a una misma base de datos.
Esto mismo lo puedes ocupar al usar algún otro patron de diseño, como Registry, con el cual puedes crear tu instancia de tu clase, y registrarla en el registro para usarla mucho más adelante, y no te limitas a usar solo una instancia por ejecución.

Saludos.
  #27 (permalink)  
Antiguo 15/04/2010, 22:06
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
De acuerdo Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
Lo que pasa es un problema clave, que pasa cuando quieres trabajar en dos bases de datos diferentes en el mismo archivo?, es ahi cuando se ve una deficiencia de usar Singleton para clases que sean conexiones.
Saludos.
Positivo, aunque existen alternativas:

Código PHP:
Ver original
  1. class DataBase {
  2. private $conexion;
  3. private $resource;
  4. private $sql;
  5. public static $queries;
  6. private static $_singleton;
  7. private static $_db;
  8. private static $_servidor;
  9.  
  10. public static function getInstance($servidor, $user, $password, $db) {
  11.    if ( (!isset (self::$_singleton)) || ($db != self::$_db) || ($_servidor != self::$_servidor) ) {
  12.           $c = __CLASS__;
  13.           self::$_singleton = new $c($servidor, $user, $password, $db);
  14.           self::$_db  = $db;  
  15.           self::$_servidor = $servidor;        
  16.         }
  17.         return self::$_singleton;
  18. }

Última edición por atrianaster; 17/04/2010 a las 18:41
  #28 (permalink)  
Antiguo 16/04/2010, 07:29
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

De todos modos, muestrame como se trabajaría en el mismo script con 2 bases de datos al mismo tiempo, de la forma que tu expones tendría que trabajar en 1 base de datos, cerrar la conexíon y abrir otra para la segunda, no pueden interactuar entre ellas, siempre es mas limpio algo así:
Código PHP:
Ver original
  1. $db = new db($datosConexionPrincipal);
  2. Registry::save('defaultDb', $db);
  3. $db2 = new db($datosSegundaConexion);
  4.  
  5. $result = $db->query("SELECT * FROM foo");
  6. while ($row = $result->fetch()) {
  7.          $db2->insert($sql);
  8. }

Al usar un patrón como Registry puedes guardar la instancia por defecto de tu clase Db y así te evitas estar creando objetos de forma innecesaria y se consigue lo que en teoría se haría con el Singleton y aparte queda la limpieza y el poder de poder usar otras bases de datos.

Saludos.
  #29 (permalink)  
Antiguo 16/04/2010, 11:17
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 7 meses
Puntos: 20
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

Cita:
Iniciado por GatorV Ver Mensaje
Al usar un patrón como Registry puedes guardar la instancia por defecto de tu clase Db y así te evitas estar creando objetos de forma innecesaria y se consigue lo que en teoría se haría con el Singleton y aparte queda la limpieza y el poder de poder usar otras bases de datos.
¿Necesitas usar el Registry en PDO para poder conectarte a dos base de datos distintas?

Muchas gracias
  #30 (permalink)  
Antiguo 16/04/2010, 12:42
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Duda con clase mysql, saber si se ejecuta 2 veces la consulta

No, el Registry simplemente es para llevar un registro de cosas y evitar estar creando objetos de forma innecesaria, en este caso puede ser una conexíon a una base de datos, u otro tipo de cosas.

Para PDO basta con instanciar dos objetos diferentes y no tienes problema.

Saludos.

Etiquetas: clase, mysql
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 17:16.