Página 1 de 1

Filtro en Php

Publicado: 30 Ene 2017, 16:27
por lean
Hola buenas tardes, recién estoy aprendiendo Php y tengo una duda espero me puedan ayudar.

Lo que pretendo es hacer otros combobox para hacer un filtrado mas concreto.

En este caso quiero listar el valores de "carrera" y "id_alumno", lo que pretendo es poder tener mas filtros para una besuqueada mas exacta.

Código: Seleccionar todo

<?php
 
////////////////// CONEXION A LA BASE DE DATOS ////////////////////////////////////
 
$host="localhost";
$usuario="root";
$contraseña="root";
$base="itic";
 
$conexion= new mysqli($host, $usuario, $contraseña, $base);
if ($conexion -> connect_errno)
{
	die("Fallo la conexion:(".$conexion -> mysqli_connect_errno().")".$conexion-> mysqli_connect_error());
}
////////////////// VARIABLES DE CONSULTA////////////////////////////////////
 
$where="";
$nombre=$_POST['xnombre'];
$carrera=$_POST['xcarrera'];
 
 
////////////////////// BOTON BUSCAR //////////////////////////////////////
 
if (isset($_POST['buscar']))
{
 
 
 
	if (empty($_POST['xcarrera']))
	{
		$where="where nombre like '".$nombre."%'";
	}
 
	else if (empty($_POST['xnombre']))
	{
		$where="where carrera='".$carrera."'";
	}
 
	else
	{
		$where="where nombre like '".$nombre."%' and carrera='".$carrera."'";
	}
}
/////////////////////// CONSULTA A LA BASE DE DATOS ////////////////////////
 
$alumnos="SELECT * FROM alumnos $where ";
$resAlumnos=$conexion->query($alumnos);
$resCarreras=$conexion->query($alumnos);
 
if(mysqli_num_rows($resAlumnos)==0)
{
	$mensaje="<h1>No hay registros que coincidan con su criterio de búsqueda.</h1>";
}
?>
<html lang="es">
 
	<head>
		<title>Filtro de Búsqueda PHP</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
 
		<link href="css/estilos.css" rel="stylesheet">
		<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
 
	</head>
	<body>
		<header>
			<div class="alert alert-info">
			<h2>Filtro de Búsqueda PHP</h2>
			</div>
		</header>
		<section>
			<form method="post">
				<input type="text" placeholder="Nombre..." name="xnombre"/>
 
				<select name="xcarrera">
					<option value="">Carrera </option>
					<?php
						while ($registroCarreras = $resCarreras->fetch_array(MYSQLI_BOTH))
						{
							echo '<option value="'.$registroCarreras['carrera'].'">'.$registroCarreras['carrera'].'</option>';
						}
 
					?>
 
 
				</select>
 
 
 
				<button name="buscar" type="submit">Buscar</button>
			</form>
			<table class="table">
				<tr>
					<th>ID_Alumno</th>
					<th>Nombre</th>
					<th>Carrera</th>
					<th>Grupo</th>
				</tr>
 
				<?php
 
				while ($registroAlumnos = $resAlumnos->fetch_array(MYSQLI_BOTH))
				{
 
					echo'<tr>
						 <td>'.$registroAlumnos['id_alumno'].'</td>
						 <td>'.$registroAlumnos['nombre'].'</td>
						 <td>'.$registroAlumnos['carrera'].'</td>
						 <td>'.$registroAlumnos['grupo'].'</td>
						 </tr>';
				}
				?>
			</table>
 
			<?php
				echo $mensaje;
			?>
		</section>
	</body>
</html>

Re: Filtro en Php

Publicado: 30 Ene 2017, 21:16
por AlfredoRamos
Justo ahora que estas aprendiendo te comento algunas cosas que necesitas corregir:

- Jamás, JAMÁS pases valores de $_POST o $_GET a una sentencia SQL sin antes sanitizarlos/escapearlos, es un gravísimo fallo de seguridad, lee acerca de sentencias preparadas e inyecciónes SQL.
- Se consistente con el modelo de programación que vas a usar, si será orientado objetos, usa todo orientado a objetos, estas mezclando procedual y orientada objetos:

Código: Seleccionar todo

$conexion= new mysqli($host, $usuario, $contraseña, $base);
...
if(mysqli_num_rows($resAlumnos)==0)
- No mezcles lógica (código) con diseño (HTML/CSS), es una mala práctica, lee hacerca del modelo MVC.
- Normaliza tus tablas, no es correcto tener la carrera y el grupo en la tabla de alumnos.

Con respecto a tu consulta, por la forma en que construyes tus consultas es más complicado generar filtros dinámicos, primero necesitas corregir lo anterior. Para generar listas dinamicas necesitarías tener una tabla para carreras y grupos para mostrarlas en la lista sin tener que generar la consulta alumnos.

Te dejo un ejemplo funcional:

Código: Seleccionar todo

SHOW TABLES;
+----------------+
| Tables_in_itic |
+----------------+
| alumnos        |
| carreras       |
| grupos         |
+----------------+

Código: Seleccionar todo

EXPLAIN alumnos;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| nombre     | varchar(50) | NO   |     | NULL    |                |
| id_carrera | int(11)     | NO   |     | NULL    |                |
| id_grupo   | int(11)     | NO   |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

Código: Seleccionar todo

EXPLAIN carreras;
+--------+-------------+------+-----+---------+----------------+
| Field  | Type        | Null | Key | Default | Extra          |
+--------+-------------+------+-----+---------+----------------+
| id     | int(11)     | NO   | PRI | NULL    | auto_increment |
| nombre | varchar(50) | NO   |     | NULL    |                |
+--------+-------------+------+-----+---------+----------------+

Código: Seleccionar todo

EXPLAIN grupos;
+--------+-------------+------+-----+---------+----------------+
| Field  | Type        | Null | Key | Default | Extra          |
+--------+-------------+------+-----+---------+----------------+
| id     | int(11)     | NO   | PRI | NULL    | auto_increment |
| nombre | varchar(50) | NO   |     | NULL    |                |
+--------+-------------+------+-----+---------+----------------+

Código: Seleccionar todo

<?php

// Datos para la conexión
$datos = [
	'host'	=> 'localhost',
	'user'	=> 'root',
	'password'	=> 'root',
	'database'	=> 'itic'
];

// Intentamos conectarnos
try {
	$pdo = new PDO(
		sprintf('mysql:host=%s;dbname=%s', $datos['host'], $datos['database']),
		$datos['user'],
		$datos['password'],
		[
			PDO::ATTR_EMULATE_PREPARES		=> false,
			PDO::ATTR_ERRMODE				=> PDO::ERRMODE_EXCEPTION,
			PDO::ATTR_DEFAULT_FETCH_MODE	=> PDO::FETCH_OBJ,
			PDO::ATTR_PERSISTENT			=> true
		]
	);
} catch (PDOException $ex) {
	// Falló la conexión
	trigger_error($ex->getMessage(), E_USER_ERROR);
}

// Especifica qué campos necesitas
$filtros = [
	'nombre',
	'id_carrera',
	'id_grupo'
];

// Guarda los valores
$valores = [];
foreach($filtros as $filtro) {
	if (!empty($_POST[$filtro])) {
		$valores[$filtro] = $_POST[$filtro];
	}
}

// Obtengo la lista de campos a filtrar
// que necesito

// Carreras
$consulta = $pdo->prepare('SELECT * FROM carreras');
$consulta->execute();
$carreras = $consulta->fetchAll();

// Grupos
$consulta = $pdo->prepare('SELECT * FROM grupos');
$consulta->execute();
$grupos = $consulta->fetchAll();

$alumnos = [];

if (isset($_POST['buscar'])) {
	// Creo la consulta para Alumnos
	$sql = 'SELECT * FROM alumnos';

	// Añado condición WHERE
	if (count($valores) > 0) {
		$ultimo = key(array_slice($valores, -1, 1));
		$sql .= ' WHERE ';

		foreach($valores as $indice => $valor) {
			$sql .= sprintf('%1$s = :%1$s', $indice);

			if (count($valores) > 1 && $indice != $ultimo) {
				$sql .= ' AND ';
			}
		}

	}

	// Opcional
	$sql .= ' LIMIT 15';

	// Obtengo los alumnos
	$consulta = $pdo->prepare($sql);
	foreach($valores as $indice => $valor) {
		$consulta->bindValue(
			sprintf(':%s', $indice),
			$valor,
			PDO::PARAM_STR
		);
	}
	$consulta->execute();
	$alumnos = $consulta->fetchAll();
}

?>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>Filtros dinámicos PHP y MySQL</title>
	</head>
	<body>
		<form method="post">
			<fieldset>
				<legend>Debug</legend>
				<?php if (!empty($sql)): ?>
				<pre><code><?php echo $sql; ?></code></pre>
				<?php endif; ?>

				<?php if (!empty($valores)): ?>
				<hr />
				<pre><code><?php
				foreach($valores as $indice => $valor) {
					echo sprintf(':%s => "%s"', $indice, $valor).PHP_EOL;
				}
				?></code></pre>
				<?php endif; ?>
			</fieldset>

			<fieldset>
				<legend>Filtrar</legend>

				<input type="text" name="nombre" placeholder="Nombre" />

				<select name="id_carrera">
					<option value="0">Carrera</option>
					<?php foreach ($carreras as $carrera): ?>
					<option value="<?php echo $carrera->id; ?>">
						<?php echo $carrera->nombre; ?>
					</option>
					<?php endforeach; ?>
				</select>

				<select name="id_grupo">
					<option value="0">Grupo</option>
					<?php foreach($grupos as $grupo): ?>
					<option value="<?php echo $grupo->id; ?>">
						<?php echo $grupo->nombre; ?>
					</option>
					<?php endforeach; ?>
				</select>

				<button type="submit" name="buscar">Buscar</button>
			</fieldset>
		</form>

		<?php if (count($alumnos) > 0): ?>
		<table>
			<thead>
				<tr>
					<th>ID</th>
					<th>Nombre</th>
					<th>Carrera</th>
					<th>Grupo</th>
				</tr>
			</thead>
			<tbody>
				<?php foreach ($alumnos as $alumno): ?>
				<tr>
					<td><?php echo $alumno->id; ?></td>
					<td><?php echo $alumno->nombre; ?></td>
					<td><?php echo $alumno->id_carrera; ?></td>
					<td><?php echo $alumno->id_grupo; ?></td>
				</tr>
				<?php endforeach; ?>
			</tbody>
		</table>
		<?php else: ?>
		<p>No se encontraron resultados</p>
		<?php endif; ?>
	</body>
</html>