[php] SELECCIONAR * FROM en MySQLi


2 Answers

Esto fue hace un mes, pero bueno.

Podría estar equivocado, pero para su pregunta tengo la sensación de que bind_param no es realmente el problema aquí. Siempre debe definir algunas condiciones, ya sea directamente en la cadena de consulta, de usar bind_param para establecer el ? marcadores de posición. Eso no es realmente un problema.

El problema que tuve al usar MySQLi SELECT * consultas es la parte bind_result . Ahí es donde se pone interesante. Me encontré con esta publicación de Jeffrey Way: (Este enlace ya no está activo). La secuencia de comandos básicamente recorre los resultados y los devuelve como una matriz; no es necesario saber cuántas columnas hay, y aún puede usar las declaraciones preparadas.

En este caso, se vería algo como esto:

$stmt = $mysqli->prepare(
  'SELECT * FROM tablename WHERE field1 = ? AND field2 = ?');
$stmt->bind_param('ss', $value, $value2);
$stmt->execute();

A continuación, use el fragmento del sitio:

$meta = $stmt->result_metadata();

while ($field = $meta->fetch_field()) {
  $parameters[] = &$row[$field->name];
}

call_user_func_array(array($stmt, 'bind_result'), $parameters);

while ($stmt->fetch()) {
  foreach($row as $key => $val) {
    $x[$key] = $val;
  }
  $results[] = $x;
}

Y $results ahora contiene toda la información de SELECT * . Hasta ahora, encontré que esta era una solución ideal.

Question

Mi sitio es bastante extenso, y recientemente hice el cambio a PHP5 (llámame bloomer tardío).

Todas mis consultas MySQL anteriores se construyeron como tal:

"SELECT * FROM tablename WHERE field1 = 'value' && field2 = 'value2'";

Esto lo hizo muy fácil, simple y amigable.

Ahora trato de hacer el cambio a mysqli por obvias razones de seguridad, y me está resultando difícil descifrar cómo implementar las mismas consultas SELECT * FROM cuando bind_param requiere argumentos específicos.

¿Es esta afirmación una cosa del pasado?

Si es así, ¿cómo manejo una consulta con toneladas de columnas involucradas? ¿De verdad necesito escribirlos todos?




Estaba buscando un buen y completo ejemplo de cómo vincular múltiples parámetros de consulta dinámicamente a cualquier consulta SELECT, INSERT, UPDATE y DELETE. Alec menciona en su respuesta una forma de vincular el resultado, para mí la función get_result () after execute () para las consultas SELECT funciona muy bien, y puedo recuperar todos los resultados seleccionados en una matriz de matrices asociativas.

De todos modos, terminé creando una función en la que puedo vincular dinámicamente cualquier cantidad de parámetros a una consulta parametrizada (usando la función call_user_func_array) y obtener un resultado de la ejecución de la consulta. A continuación se muestra la función con su documentación (por favor, lea antes antes de usarla, especialmente los $ paresmeterTypes - El parámetro caracteres de especificación de caracteres es importante de entender)

     /**
     * Prepares and executes a parametrized QUERY (SELECT, INSERT, UPDATE, DELETE)
     *
     * @param[in] $dbConnection mysqli database connection to be used for query execution
     * @param[in] $dbQuery parametrized query to be bind parameters for and then execute
     * @param[in] $isDMQ boolean value, should be set to TRUE for (DELETE, INSERT, UPDATE - Data manipulaiton queries), FALSE for SELECT queries
     * @param[in] $paremetersTypes String representation for input parametrs' types as per http://php.net/manual/en/mysqli-stmt.bind-param.php
     * @param[in] $errorOut A variable to be passed by reference where a string representation of an error will be present if a FAUILURE occurs
     * @param[in] $arrayOfParemetersToBind Parameters to be bind to the parametrized query, parameters need to be specified in an array in the correct order 
     * @return array of feched records associative arrays for SELECT query on SUCCESS, TRUE for INSERT, UPDATE, DELETE queries on SUCCESS, on FAIL sets the error and returns NULL 
     */
    function ExecuteMySQLParametrizedQuery($dbConnection, $dbQuery, $isDMQ, $paremetersTypes, &$errorOut, $arrayOfParemetersToBind)
    {
        $stmt = $dbConnection->prepare($dbQuery);

        $outValue = NULL;

        if ($stmt === FALSE)
            $errorOut = 'Failed to prepare statement for query: ' . $dbQuery;
        else if ( call_user_func_array(array($stmt, "bind_param"), array_merge(array($paremetersTypes), $arrayOfParemetersToBind)) === FALSE)
            $errorOut = 'Failed to bind required parameters to query: ' . $dbQuery . '  , parameters :' . json_encode($arrayOfParemetersToBind);
        else if (!$stmt->execute())
            $errorOut = "Failed to execute query [$dbQuery] , erorr:" . $stmt->error;
        else
        {
            if ($isDMQ)
               $outValue = TRUE;
            else
            {
                $result = $stmt->get_result();

                if ($result === FALSE) 
                     $errorOut = 'Failed to obtain result from statement for query ' . $dbQuery;
                else
                    $outValue = $result->fetch_all(MYSQLI_ASSOC);
            }
        }

        $stmt->close();

        return $outValue;
    }

uso:

    $param1 = "128989";
    $param2 = "some passcode";


    $insertQuery = "INSERT INTO Cards (Serial, UserPin) VALUES (?, ?)";
    $rowsInserted = ExecuteMySQLParametrizedQuery($dbConnection, $insertQuery, TRUE, 'ss', $errorOut, array(&$param1, &$param2) ); // Make sure the parameters in an array are passed by reference

    if ($rowsInserted === NULL)
        echo 'error ' . $errorOut;
    else
        echo "successfully inserted row";


    $selectQuery = "SELECT CardID FROM Cards WHERE Serial like ? AND UserPin like ?";
    $arrayOfCardIDs = ExecuteMySQLParametrizedQuery($dbConnection, $selectQuery, FALSE, 'ss', $errorOut, array(&$param1, &$param2) ); // Make sure the parameters in an array are passed by reference

    if ($arrayOfCardIDs === NULL) 
        echo 'error ' . $errorOut;
    else
    {
        echo 'obtained result array of ' . count($arrayOfCardIDs) . 'selected rows';

        if (count($arrayOfCardIDs) > 0) 
            echo 'obtained card id = ' . $arrayOfCardIDs[0]['CardID'];
    }



Todavía puede usarlo (mysqli es simplemente otra forma de comunicarse con el servidor, el lenguaje SQL mismo se expande, no se cambia). Sin embargo, las declaraciones preparadas son más seguras, ya que no es necesario que se tome la molestia de escapar correctamente de sus valores cada vez. Puede dejarlos como estaban, si lo desea, pero el riesgo de sql piggybacking se reduce si cambia.




Related



Tags

php php   mysqli