'Algoritmo' de búsqueda PHP

B

Buenas noches, tengo que hacer una búsqueda en una base de datos y es la primera vez que lo hago, yo lo hice de esta forma, funciona. pero me gustaría saber si esto es lo correcto o hay una mejor forma de hacerlo.

Tendremos 4 variables

TipoPropiedad
TipoOperacion
CantidadDormitorios
CantidadBanios

Si TipoPropiedad es 1 o 2 entonces deberemos utilizar (CantidadDormitorios, CantidadBanios y TipoOperacion) en la búsqueda
Si TipoPropiedad es 3 entonces deberemos utilizar (CantidadBanios y TipoOperacion) en la búsqueda
Si TipoPropiedad > 3 entonces solo (TipoOperacion)

Ahora tendremos varios valores tanto en CantidadDormitorios

1 (Equivalen a 1 Cantidad de dormitorios)
2 (Equivalen a 2 Cantidad de dormitorios)
3 (Equivalen a 3 Cantidad de dormitorios)
4 (Equivalen a 4 Cantidad de dormitorios)
5 (Equivalen a 5 Cantidad de dormitorios)
66 (Equivalen a +6 Cantidad de dormitorios)
12 (Equivalen a 1 o 2 Cantidad de dormitorios)
34 (Equivalen a 2 o 3 Cantidad de dormitorios)
45 (Equivalen a 4 o 5 Cantidad de dormitorios)

Y valores similares en CantidadBanios

1 (Equivalen a 1 Cantidad de baños)
2 (Equivalen a 2 Cantidad de baños)
3 (Equivalen a 3 Cantidad de baños)
4 (Equivalen a 4 Cantidad de baños)
5 (Equivalen a 5 Cantidad de baños)
66 (Equivalen a +6 Cantidad de baños)
12 (Equivalen a 1 o 2 Cantidad de baños)
34 (Equivalen a 2 o 3 Cantidad de baños)
45 (Equivalen a 4 o 5 Cantidad de baños)

Yo lo hice de la siguiente forma, así me funciona aunque me quedó un poco extenso

Por alguna razón el (code) se ve mal, acá https://pastebin.com/J4D5pLpy esta taburado y con comentarios


if($TipoPropiedad == 1 || $TipoPropiedad == 2 && $CantidadDormitorios >= 1 && $CantidadBanios >= 1) {

if($CantidadDormitorios > 5 && $CantidadDormitorios != 66) { $Dormitorios = str_split($CantidadDormitorios); } # Si CantidadDormitorios es 12 o 23 o 34 entonces lo divido en 2 para usar un OR en la consulta, también podría usar un between
if($CantidadBanios > 5 && $CantidadBanios != 66) { $Banios = str_split($CantidadBanios); } # Si CantidadBanios es 12 o 23 o 34 entonces lo divido en 2 para usar un OR en la consulta, también podría usar un between

if(!isset($Dormitorios) && !isset($Banios)) { # Si CantidadDormitorios y CantidadBanios no existen (es decir que los valores pueden ser 1, 2, 3, 4, 5 o 66)

	if($CantidadDormitorios != 66 && $CantidadBanios != 66) { # Si CantidadDormitorios y CantidadBanios valen (1, 2, 3, 4 o 5)
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND Banios<=? AND Dormitorios<=? AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion, $CantidadBanios, $CantidadDormitorios];
	}
	elseif($CantidadDormitorios == 66 && $CantidadBanios == 66) { # Si CantidadDormitorios y CantidadBanios valen +6
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND Banios>=6 AND Dormitorios>=6 AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion];
	}
	elseif($CantidadDormitorios == 66 && $CantidadBanios != 66) { # Si CantidadDormitorios vale +6 y CantidadBanios (1, 2, 3, 4 o 5)
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND Banios<=? AND Dormitorios>=6 AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion, $CantidadBanios];
	}
	elseif($CantidadDormitorios != 66 && $CantidadBanios == 66) { # Si CantidadDormitorios vale (1, 2, 3, 4 o 5) y CantidadBanios +6
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND Banios>=6 AND Dormitorios<=? AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion, $CantidadDormitorios];
	}
} elseif(isset($Dormitorios) && !isset($Banios)) { # Acá CantidadDormitorios podría valer 12, 23, 34 o 45 pero CantidadBanios solo (1, 2, 3, 4, 5 o 66)

	if($CantidadBanios != 66) { # Si CantidadBanios vale (1, 2, 3, 4 o 5)
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND (Dormitorios=? OR Dormitorios=?) AND Banios=? AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion, $Dormitorios[0], $Dormitorios[1], $CantidadBanios];
	} else { # Si CantidadBanios vale +6
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND (Dormitorios=? OR Dormitorios=?) AND Banios>=6 AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion, $Dormitorios[0], $Dormitorios[1]];
	}				
} elseif(!isset($Dormitorios) && isset($Banios)) { # Acá CantidadDormitorios podría valer (1, 2, 3, 4, 5 o 66) y CantidadBanios podría valer 12, 23, 34 o 45

	if($CantidadDormitorios != 66) {  # Si CantidadDormitorios vale (1, 2, 3, 4 o 5)
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND Dormitorios=? AND (Banios=? OR Banios=?) AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion, $CantidadDormitorios, $Banios[0], $Banios[1]];
	} else { # Si CantidadDormitorios vale +6
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND Dormitorios>=6 AND (Banios=? OR Banios=?) AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion, $Banios[0], $Banios[1]];
	}

} elseif(isset($Dormitorios) && isset($Banios)) { # Acá tanto como CantidadDormitorios y CantidadBanios podrían valer 12, 23, 34, 45
	$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND (Dormitorios=? OR Dormitorios=?) AND (Banios=? OR Banios=?) AND (EstadoOp=1 OR EstadoOp=2)");
	$datos = [$TipoPropiedad, $TipoOperacion, $Dormitorios[0], $Dormitorios[1], $Banios[0], $Banios[1]];
}
} elseif($TipoPropiedad == 3) { # Acá solo debo comprobar CantidadBanios y sus variaciones

if($CantidadBanios > 5 && $CantidadBanios != 66) { $Banios = str_split($CantidadBanios); }

if(isset($Banios)) { # Si CantidadBanios vale 12, 23, 34 o 45
	$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND (Banios=? OR Banios=?) AND (EstadoOp=1 OR EstadoOp=2)");
	$datos = [$TipoPropiedad, $TipoOperacion, $Banios[0], $Banios[1]];
} else {
	if($CantidadBanios == 66) { # Si CantidadBanios es +6
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND Banios>=6 AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion];
	} else { # Si CantidadBanios es (1, 2, 3, 4 o 5)
		$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND Banios>=? AND (EstadoOp=1 OR EstadoOp=2)");
		$datos = [$TipoPropiedad, $TipoOperacion, $CantidadBanios];
	}
}
} else { # Acá consulto directo porque TipoPropiedad > 3
	$BuscarPropiedad = $pdo->prepare("SELECT id, Title FROM Propiedades WHERE TipoProp=? AND TipoOp=? AND (EstadoOp=1 OR EstadoOp=2)");
	$datos = [$TipoPropiedad, $TipoOperacion];
}

Agradecería mucho su opinión, no me sorprendería que sea una basura porque no tengo mucha experiencia haciendo esto

MartiONE

Hombre, no soy muy experto en PHP pero estas haciendo la misma consulta prácticamente todo el rato, no veo la necesidad de estar añadiendo esa cantidad de bloques if/else cuando simplemente puedes modificar el string de la llamada SQL para que se adapte a los parámetros que le estas añadiendo.

1 respuesta
vivora

#2 Al final en todos los lenguajes es lo mismo. Yo lo que haría dentro de los IF simplemente es definir el $datos. Después un array para el Where:

$Where = array()
Y cada condición de AND lo metes como una entrada del array:
$Where[] = 'EstadoOp=1 OR EstadoOp=2'
$Where[]='TipoOp=?'
...

Después en la última función haces un implode(' AND ', $Where) y pista.

Esto realmente para "mejorar" un poco como lo has hecho. Pero lo suyo es tener una función que haga todas las conexiones con la base de datos, y pasarle los parámetros que crear necesarios. Incluso puedes tener un parámetros $Options para cambiar el comportamiento (decidir si tiene que devolver baños o no, etc)

Usuarios habituales