Saltar al contenido

¿Es posible que la consulta PHP MYSQL ignore la variable vacía en la cláusula WHERE?

Posteriormente a consultar con especialistas en el tema, programadores de diversas ramas y profesores dimos con la respuesta a la cuestión y la dejamos plasmada en esta publicación.

Solución:

Usar

$where = "WHERE user_id = '$username'";

if(!empty($value1))
$where .= "and location = '$value1'";


if(!empty($value2 ))
$where .= "and english_name= '$value2 '";



$query = "SELECT * FROM moth_sightings $where";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);

Varias otras respuestas mencionan el riesgo de inyección de SQL, y un par mencionan explícitamente el uso de declaraciones preparadas, pero ninguna de ellas muestra explícitamente cómo podría hacerlo, lo que podría ser una gran pregunta para un principiante.

Mi método preferido actual para resolver este problema utiliza una declaración “IF” de MySQL para verificar si el parámetro en cuestión es null/vacío/0 (dependiendo del tipo). Si está vacío, compara el valor del campo consigo mismo ( WHERE field1=field1 siempre regresa true). Si el parámetro no está vacío/null/cero, el valor del campo se compara con el parámetro.

Entonces, aquí hay un ejemplo que usa declaraciones preparadas de MySQLi (suponiendo que $mysqli es un objeto mysqli ya instanciado):

$sql = "SELECT * 
        FROM moth_sightings 
        WHERE user_id = ? 
            AND location = IF(? = '', location, ?)
            AND english_name = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ssss', $username, $value1, $value1, $value2);
$stmt->execute();

(supongo que $value2 es un string basado en el nombre del campo, a pesar de la falta de comillas en el SQL de ejemplo de OP).

No hay forma en MySQLi de vincular el mismo parámetro a múltiples marcadores de posición dentro de la declaración, por lo que tenemos que vincular explícitamente $value1 dos veces. La ventaja que tiene MySQLi en este caso es la tipificación explícita del parámetro – si pasamos $value1 como un stringsabemos que necesitamos compararlo con el vacío string ''. Si $value1 fuera un valor entero, podríamos declararlo explícitamente así:

$stmt->bind_param('siis', $username, $value1, $value1, $value2);

y compararlo contra 0 en lugar de.

Aquí hay un ejemplo de PDO que usa parámetros con nombre, porque creo que dan como resultado un código mucho más legible con menos conteo:

$sql = "SELECT * 
    FROM moth_sightings 
    WHERE user_id = :user_id 
        AND location = IF(:location_id = '', location, :location_id)
        AND english_name = :name";
$stmt = $pdo->prepare($sql);
$params = [
    ':user_id' => $username,
    ':location_id' => $value1,
    ':name' => $value2
];
$stmt->execute($params);

Tenga en cuenta que con los parámetros con nombre PDO, podemos referirnos a :location_id varias veces en la consulta y solo tiene que vincularla una vez.

Puntuaciones y comentarios

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *