Foros del Web » Programando para Internet » PHP »

Generalizar prepared statements

Estas en el tema de Generalizar prepared statements en el foro de PHP en Foros del Web. Hola. Estoy trabajando con prepared statements y quiero generalizar para un número X de columnas de la consulta. El código que utilizo, el cual es ...
  #1 (permalink)  
Antiguo 15/12/2008, 20:27
 
Fecha de Ingreso: marzo-2005
Mensajes: 1.418
Antigüedad: 19 años, 1 mes
Puntos: 9
Generalizar prepared statements

Hola. Estoy trabajando con prepared statements y quiero generalizar para un número X de columnas de la consulta. El código que utilizo, el cual es una adaptación de un código que encontré en la red, es el siguiente:

Código:
function db_pquery_resultset()
{
    global $DB_CONN;
    global $DB_STMT;
    
    mysqli_stmt_execute($DB_STMT);
    
    $meta = mysqli_stmt_result_metadata($DB_STMT);
    $params[0] = &$DB_STMT;
    $index = 1;
    while ($field = mysqli_fetch_field($meta))
    {
        $params[$index++] = &$row[$field->name];
    } 
    
    call_user_func_array('mysqli_stmt_bind_result', $params);

    $index = 0;

    while (mysqli_stmt_fetch($DB_STMT)) {
            foreach($row as $key => $val)
            {
                $c[$key] = $val;
            }
            $result[$index++] = $c;
        }
        
    print_r($result);

    mysqli_stmt_close($DB_STMT);    
    

    
    
}
Antes de ejecutar esta función, inicializo la consulta y hago el enlace de los parametros que recibe la consulta parametrizada (valga la redundancia). Una vez finalizado esto, entonces si ejecuto esta función. Cuando, ejecuto la línea marcada en rojo, se me muestra por pantalla algo así:

Array ( [0] => Array ( [nombre_columna1] => valor_columna1 [nombre_columna2] => valor_columna2 ) )

Pero esto no es lo que quiero. Lo que me gustaría hacer es crear un array multidimensional para poder acceder a los valores de cada fila-columna de esta forma:

$resultset[$indice_fila][$indice_columna].
¿Existe alguna forma de hacerlo?.

Algo que no entiendo del código es que función cumple el operador '&'. ¿Es el operador de dirección, al igual que en C?.
__________________
Add, never Remove
  #2 (permalink)  
Antiguo 15/12/2008, 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
Puntos: 2135
Respuesta: Generalizar prepared statements

Pues eso es lo que hace el codigo que pusiste... si te fijas en el print_r te esta marcando que el indice 0 es un arreglo con las cosas, asi que puedes usar claramente $result[$num_fila][$nombre_columna].

El operador & sirve para pasar el puntero de la variable en lugar del valor de la variable, es un tema un poco complejo pero si buscas en google sobre punteros se te va a hacer sencillo.

Saludos.
  #3 (permalink)  
Antiguo 15/12/2008, 21:04
 
Fecha de Ingreso: marzo-2005
Mensajes: 1.418
Antigüedad: 19 años, 1 mes
Puntos: 9
Si hago por ejemplo $result[0][0] no me muestra nada. La consulta que estoy realizando tendría que arrojar un resultado que consta de un solo registro, pero de esta forma no accedo a los valores.
Si, es un tema complejo, pero por suerte ya pase esa etapa de andar desorientado con los punteros. Manejé bastante de ellos en C hace un tiempo para un proyecto de la facultad.
Gracias gatorv por tu respuesta.
Saludos.

Perdon gatorv, leí apurado tu post y no vi que me marcabas $result[$num_fila][$nombre_columna]. Pude solucionarlo de esa forma. Gracias de nuevo.
Saludos.

Volví a modificar la función anterior para que en lugar de acceder a los resultados como un array asociativo pueda accederlo por sus índices. Así es como me quedó:

Código:
function db_pquery_resultset()
{
    global $DB_CONN;
    global $DB_STMT;
    
    mysqli_stmt_execute($DB_STMT);
    
    $meta = mysqli_stmt_result_metadata($DB_STMT);
    $params[0] = &$DB_STMT;
    $fields_count = mysqli_num_fields($meta);
    
    $index = 1;
    for ( $i=0 ; $i<$fields_count ; $i++ )
        $params[$index++] = &$cols[$i];

    call_user_func_array('mysqli_stmt_bind_result', $params);

    $index = 0;
    while (mysqli_stmt_fetch($DB_STMT))
    {
        for ( $i=0 ; $i<$fields_count ; $i++ )
            $resultset_cols[$i] = $cols[$i];
        $result[$index++] = $resultset_cols;
    }
        
    echo($result[0][0]);
    
    mysqli_stmt_close($DB_STMT);    
    
}
En la parte del código que está remarcada en negrita, hago una copia exacta de cada fila del resultset y luego lo añado al resultado que devuelvo. Mi pregunta es ¿Por qué es necesario realizar esta copia? ¿Por qué no puedo ejecutar la sentencia $result[$index++] = $cols;?. Me fije en la página donde obtuve el código y no dice nada al respecto.
Saludos.
__________________
Add, never Remove

Última edición por GatorV; 15/12/2008 a las 23:08
  #4 (permalink)  
Antiguo 15/12/2008, 23:08
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: Generalizar prepared statements

Que problema te da usarlo directamente (solo quita el for), no veo ningun problema que hagas esto:
Código php:
Ver original
  1. while (mysqli_stmt_fetch($DB_STMT))
  2.     {
  3.         $result[$index++] = $resultset_cols;
  4.     }

Saludos.
  #5 (permalink)  
Antiguo 15/12/2008, 23:23
 
Fecha de Ingreso: marzo-2005
Mensajes: 1.418
Antigüedad: 19 años, 1 mes
Puntos: 9
Respuesta: Generalizar prepared statements

Pero para que $resultset_cols esté definido, necesito entrar al bucle. ¿Habrás querido poner $cols?. Si es eso, no me arroja ningún error, simplemente que me muestra en todos las filas el mismo resultado.
__________________
Add, never Remove
  #6 (permalink)  
Antiguo 16/12/2008, 10:59
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: Generalizar prepared statements

Cierto es $cols, pero ahora que veo como estas referenciando directamente a $cols (el puntero) por lo que si te va a ser necesario copiar el dato a la otra columna.

Saludos.
  #7 (permalink)  
Antiguo 16/12/2008, 11:36
 
Fecha de Ingreso: marzo-2005
Mensajes: 1.418
Antigüedad: 19 años, 1 mes
Puntos: 9
Respuesta: Generalizar prepared statements

¿Tengo forma de evitarlo haciendo el código de otra manera?. No me doy cuenta si existe alguna forma. Quizás no esté entendiendo bien el código. En estas líneas tengo las dudas (comento debajo de cada una de estas como pienso yo que trabajan, por favor hacer un comentario si es incorrecto lo que estoy diciendo):

Código php:
Ver original
  1. for ( $i=0 ; $i<$fields_count ; $i++ )
  2.         $params[$index++] = &$cols[$i];

Acá estamos transformando a $params en un array de direcciones de memoria. Estas, apuntan a los espacios en memoria correspondientes al array $cols.

Código php:
Ver original
  1. call_user_func_array('mysqli_stmt_bind_result', $params);

Después de ejecutarse esta línea, dejamos establecido que en posteriores llamadas a mysqli_stmt_fetch() se guarden los valores de cada columna (de la fila que está siendo analizada) en el array $cols.

Código php:
Ver original
  1. $index = 0;
  2.     while (mysqli_stmt_fetch($DB_STMT))
  3.     {
  4.         for ( $i=0 ; $i<$fields_count ; $i++ )
  5.             [B]$resultset_cols[$i] = $cols[$i];[/B]
  6.         $result[$index++] = $resultset_cols;
  7.     }

Acá hacemos una copia exacta del array $cols al array $resultset_cols, y asignamos este al array $result, que va a ser el array que contiene la totalidad de los registros devueltos.
Sigo sin ver porque funciona de esta forma y no asignando directamente el array $cols.
Estaría muy agradecido si me podés marcar en donde es que estoy referenciando directamente a $cols.
Gracias por tu respuesta gatorv.
Saludos.
__________________
Add, never Remove
  #8 (permalink)  
Antiguo 16/12/2008, 12:13
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: Generalizar prepared statements

Porque como te dije, $cols contiene direcciones de memoria de los resultados, al tu copiarla a tu arreglo, $result va cambiando conforme las llamadas a mysqli_stmt_fetch se vayan haciendo, es por eso que tienes que copiar el valor de cada $cols y pasarlos a $result ya como valores, no como direcciones.

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 00:13.