usando una tabla registros obtener mostrar listar insertar guardar formulario extraer ejemplos desde datos con como php sql mysql prepared-statement

registros - mostrar datos de mysql en php en una tabla html



Declaraciones preparadas de MySQL con una lista de variables de tamaƱo variable (7)

Por favor toma el # 2 de la mesa. Las declaraciones preparadas son la única forma en que debe considerar protegerse contra la inyección de SQL.

Sin embargo, lo que puede hacer es generar un conjunto dinámico de variables vinculantes. es decir, no hagas 100 si necesitas 7 (o 103).

¿Cómo escribirías una declaración de MySQL preparada en PHP que toma una cantidad diferente de argumentos cada vez? Un ejemplo de tal consulta es:

SELECT `age`, `name` FROM `people` WHERE id IN (12, 45, 65, 33)

La cláusula IN tendrá una cantidad diferente de id cada vez que se ejecute.

Tengo dos soluciones posibles en mi mente pero quiero ver si hay una mejor manera.

Solución posible 1 Haga que la instrucción acepte 100 variables y complete el resto con valores ficticios que garanticen que no están en la tabla; hacer múltiples llamadas para más de 100 valores.

Posible solución 2 No use una declaración preparada; construya y ejecute la consulta comprobando rigurosamente posibles ataques de inyección.


Puedo pensar en un par de soluciones.

Una solución podría ser crear una tabla temporal. Haga una inserción en la tabla para cada parámetro que tendría en la cláusula in. Luego haz una simple combinación contra tu tabla temporal.

Otro método podría ser hacer algo como esto.

$dbh=new PDO($dbConnect, $dbUser, $dbPass); $parms=array(12, 45, 65, 33); $parmcount=count($parms); // = 4 $inclause=implode('','',array_fill(0,$parmcount,''?'')); // = ?,?,?,? $sql=''SELECT age, name FROM people WHERE id IN (%s)''; $preparesql=sprintf($sql,$inclause); // = example statement used in the question $st=$dbh->prepare($preparesql); $st->execute($parms);

Sospecho, pero no tengo pruebas, que la primera solución podría ser mejor para listas más grandes, y la última funcionaría para listas más pequeñas.

Hacer feliz a @orrd aquí es una versión concisa.

$dbh=new PDO($dbConnect, $dbUser, $dbPass); $parms=array(12, 45, 65, 33); $st=$dbh->prepare(sprintf(''SELECT age, name FROM people WHERE id IN (%s)'', implode('','',array_fill(0,count($parms),''?'')))); $st->execute($parms);


Si solo está utilizando valores enteros en su cláusula IN , no hay nada que impida construir su consulta dinámicamente sin el uso de parámetros SQL.

function convertToInt(&$value, $key) { $value = intval($value); } $ids = array(''12'', ''45'', ''65'', ''33''); array_walk($ids, ''convertToInt''); $sql = ''SELECT age, name FROM people WHERE id IN ('' . implode('', '', $ids) . '')''; // $sql will contain SELECT age, name FROM people WHERE id IN (12, 45, 65, 33)

Pero sin duda la solución here es el enfoque más general de este problema.


También está la función FIND_IN_SET cuyo segundo parámetro es una cadena de valores separados por comas:

SELECT age, name FROM people WHERE FIND_IN_SET(id, ''12,45,65,33'')


Tuve un problema similar hoy y encontré este tema. Al mirar las respuestas y buscar en google encontré una solución bonita.

Aunque, mi problema es un poco más complicado. Porque también he corregido los valores de enlace y la dinámica .

Esta es la solución.

$params = array() $all_ids = $this->get_all_ids(); for($i = 0; $i <= sizeof($all_ids) - 1; $i++){ array_push($params, $all_ids[$i][''id'']); } $clause = implode('','', array_fill(0, count($params), ''?'')); // output ?, ?, ? $total_i = implode('''', array_fill(0, count($params), ''i'')); // output iiii $types = "ss" . $total_i; // will reproduce : ssiiii ..etc // %% it''s necessary because of sprintf function $query = $db->prepare(sprintf("SELECT * FROM clients WHERE name LIKE CONCAT(''%%'', ?, ''%%'') AND IFNULL(description, '''') LIKE CONCAT(''%%'', ?, ''%%'') AND id IN (%s)", $clause)); $thearray = array($name, $description); $merge = array_merge($thearray, $params); // output: "John", "Cool guy!", 1, 2, 3, 4 // We need to pass variables instead of values by reference // So we need a function to that call_user_func_array(''mysqli_stmt_bind_param'', array_merge (array($query, $types), $this->makeValuesReferenced($merge)));

Y la función makeValuesreferenced :

public function makeValuesReferenced($arr){ $refs = array(); foreach($arr as $key => $value) $refs[$key] = &$arr[$key]; return $refs; }

Enlaces para obtener este "know-how": https://bugs.php.net/bug.php?id=49946 , PHP anexa una matriz a otra (no array_push o +) , [PHP]: Error -> Muy pocos argumentos en sprintf (); , http://no2.php.net/manual/en/mysqli-stmt.bind-param.php#89171 , Pasa por problema de referencia con PHP 5.3.1


envoltorios decentes de sql admiten enlaces a valores de matriz. es decir

$sql = "... WHERE id IN (?)"; $values = array(1, 2, 3, 4); $result = $dbw -> prepare ($sql, $values) -> execute ();


recibí mi respuesta de: http://bugs.php.net/bug.php?id=43568
esta es mi solución de trabajo para mi problema. Ahora puedo usar dinámicamente tantos parámetros como quiera. Serán el mismo número que tengo en una matriz o como en este caso estoy pasando los ID de la última consulta (que encontró todos los identificadores donde email = ''[email protected]'') a la consulta dinámica para obtener todos la información sobre cada uno de estos id. no importa cuántos necesite.

<?php $NumofIds = 2; //this is the number of ids i got from the last query $parameters=implode('','',array_fill(0,$NumofIds,''?'')); // = ?,? the same number of ?''s as ids we are looking for<br /> $paramtype=implode('''',array_fill(0,$NumofIds,''i'')); // = ii<br/> //make the array to build the bind_param function<br/> $idAr[] = $paramtype; //''ii'' or how ever many ?''s we have<br/> while($statement->fetch()){ //this is my last query i am getting the id out of<br/> $idAr[] = $id; } //now this array looks like this array:<br/> //$idAr = array(''ii'', 128, 237); $query = "SELECT id,studentid,book_title,date FROM contracts WHERE studentid IN ($parameters)"; $statement = $db->prepare($query); //build the bind_param function call_user_func_array (array($statement, "bind_param"), $idAr); //here is what we used to do before making it dynamic //statement->bind_param($paramtype,$v1,$v2); $statement->execute(); ?>