Conexion + execute()En esta clase NO creamos bases de datos ni tablas. Vamos a conectarnos a la BD que ya creamos antes y vamos a ejecutar consultas SELECT y mostrarlas en pantalla con PHP.
Vamos a crear un espacio de trabajo mínimo (mini-proyecto) con estos objetivos:
Conexion (solo __construct()).Functions (solo execute($layout)).usuarios).num_rows para contar filasfetch_assoc() para obtener cada fila como arregloforeach ($row as $key => $value) { $$key = $value; }curso_practica) y sus tablas
(por ejemplo usuarios). Si no existe, se usa el script de SQL de clases anteriores.
Esto es lo que vamos a tener en el mini-proyecto (no frameworks, no MVC, solo orden):
/mini_php_mysql_select
/config
db.php
/lib
Conexion.php
Functions.php
/pages
usuarios_list.php
index.php
/assets
/css
style.css
/js
copy.js
Qué hace cada cosa:
config/db.php → guarda credenciales (host, user, pass, db, port).lib/Conexion.php → abre la conexión a MySQL con mysqli (solo constructor).lib/Functions.php → define execute($layout) y regresa un resultado estandarizado.pages/usuarios_list.php → hace SELECT y muestra resultados en tabla.index.php → landing simple con link al listado.Conexion (solo __construct)
Esta clase existe para que tú puedas hacer esto en cualquier parte del proyecto:
$db = new Conexion(); y ya tengas una conexión lista.
Nota: la clase Conexion extiende mysqli. Eso significa que hereda métodos como:
query(), insert_id, error, etc.
Functions (solo execute($layout))
Esta clase existe para centralizar la ejecución y estandarizar el resultado.
El método recibe un texto SQL ($layout) y regresa un arreglo con información útil.
public function execute($layout)
{
$db = new Conexion(); // 1) abre conexión
$sql = $layout; // 2) el SQL recibido
$query = $db->query($sql); // 3) ejecuta
if ($query) {
$result['query'] = $query; // 4) el resultado (mysqli_result) si aplica
$result['lastId'] = $db->insert_id; // 5) id insertado (hoy no lo usamos, pero ya queda estándar)
$result['res'] = 'ok'; // 6) bandera ok
} else {
$result['res'] = 'error: ' . $db->error; // 7) error del motor
}
return $result;
}
$db = new Conexion() → crea un objeto de conexión (esto ejecuta el constructor y deja listo MySQL).$query = $db->query($sql) → ejecuta el SQL. Si fue SELECT, devuelve un objeto mysqli_result.$result['query'] → aquí tú decides el nombre del “campo” donde guardar el resultado. Nosotros le llamamos query por convenio.$result['res'] → te dice si fue ok o error.$result['lastId'] → hoy no lo usaremos porque solo haremos SELECT, pero se deja estándar para la próxima clase.query NO es “mágica”.data, result o como quieras,
pero si la cambias, debes cambiarla en todo tu código.
Paso 1: incluir clases y crear el objeto Functions.
require_once __DIR__ . '/../lib/Conexion.php';
require_once __DIR__ . '/../lib/Functions.php';
$functions = new Functions();
Paso 2: ejecutar el SELECT con execute().
$getUsers = $functions->execute("
SELECT id, nombre, correo, rol, activo, created_at
FROM usuarios
ORDER BY id DESC
");
Paso 3: validar resultado.
if ($getUsers['res'] !== 'ok') {
die($getUsers['res']); // imprime error del motor
}
Paso 4: usar num_rows para contar filas.
$totalFilas = $getUsers['query']->num_rows;
$getUsers['query'] es un mysqli_result. Ese objeto trae la propiedad
num_rows que indica cuántas filas devolvió el SELECT.
Paso 5: recorrer filas con fetch_assoc().
while ($row = $getUsers['query']->fetch_assoc()) {
// $row es un array asociativo: ['id'=>..., 'nombre'=>..., 'correo'=>...]
}
null y se termina el while.
En muchos proyectos (como el tuyo) se usa este patrón:
while ($row = $getUsers['query']->fetch_assoc()) {
foreach ($row as $key => $value) {
$$key = $value; // crea una variable con el nombre de la columna
}
// Ahora existen variables:
// $id, $nombre, $correo, $rol, $activo, $created_at, etc.
echo $nombre . " - " . $correo . "<br>";
}
$key contiene el nombre de la columna (por ejemplo "nombre").$$key se vuelve $nombre y le asigna el valor correspondiente.
Esta página es exactamente lo que debe hacer pages/usuarios_list.php: ejecutar un SELECT y dibujar una tabla.
require_once __DIR__ . '/../lib/Conexion.php';
require_once __DIR__ . '/../lib/Functions.php';
$functions = new Functions();
$getUsers = $functions->execute("
SELECT id, nombre, correo, rol, activo, created_at
FROM usuarios
ORDER BY id DESC
");
if ($getUsers['res'] !== 'ok') die($getUsers['res']);
?>
<table border="1" cellpadding="6">
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Correo</th>
<th>Rol</th>
<th>Activo</th>
</tr>
<?php while ($row = $getUsers['query']->fetch_assoc()) { ?>
<?php foreach ($row as $key => $value) { $$key = $value; } ?>
<tr>
<td><?php echo $id; ?></td>
<td><?php echo $nombre; ?></td>
<td><?php echo $correo; ?></td>
<td><?php echo $rol; ?></td>
<td><?php echo $activo; ?></td>
</tr>
<?php } ?>
</table>
Estos prompts están diseñados para que el resultado genere EXACTAMENTE las carpetas y archivos que estamos explicando. Ejecuta en orden.
Actúa como desarrollador PHP (procedural) para un mini proyecto de clase.
Objetivo del mini proyecto:
- Conectar PHP a MySQL con mysqli.
- Usar EXACTAMENTE este patrón:
1) class Conexion extends mysqli (solo __construct)
2) class Functions (solo execute($layout))
- Por ahora SOLO haremos SELECT y mostrar datos en HTML.
- No uses frameworks ni routers.
REQUISITO DE ESTA RESPUESTA:
No escribas código. SOLO entrega el árbol de carpetas y archivos con rutas.
Estructura requerida (debe ser exactamente esta):
/mini_php_mysql_select
/config
db.php
/lib
Conexion.php
Functions.php
/pages
usuarios_list.php
index.php
/assets
/css
style.css
/js
copy.js
La BD ya existe (por ejemplo: curso_practica) y la tabla usuarios ya existe.
En tu árbol no incluyas scripts de create database o create table.
Ahora genera TODO el código del proyecto usando el árbol exacto.
Reglas:
- Entrega archivo por archivo con este formato exacto:
=== ruta/archivo.ext ===
(código completo)
- No omitas archivos.
- No agregues archivos extra.
Requisitos por archivo:
1) config/db.php
- Debe retornar un arreglo (return [ ... ]) con:
host, user, pass, db, port
- Valores de ejemplo (editables):
host: 127.0.0.1
user: root
pass: (vacío o 'root123' de ejemplo)
db: curso_practica
port: 3306
2) lib/Conexion.php
- Debe contener: class Conexion extends mysqli
- SOLO método: public function __construct()
- Debe leer config/db.php con require
- Debe llamar:
parent::__construct(host, user, pass, db, port)
- Debe ejecutar:
$this->set_charset('utf8mb4');
$this->query("SET SESSION time_zone = '-06:00'");
- Si hay error:
die("Error en la conexión: " . $this->connect_error);
3) lib/Functions.php
- Debe contener: class Functions
- SOLO método: public function execute($layout)
- Debe ser EXACTAMENTE así (estructura):
$db = new Conexion();
$sql = $layout;
$query = $db->query($sql);
if ($query) {
$result['query'] = $query;
$result['lastId'] = $db->insert_id;
$result['res'] = 'ok';
} else {
$result['res'] = 'error: ' . $db->error;
}
return $result;
4) index.php
- Landing simple con Bootstrap 5 CDN
- Un botón o link a pages/usuarios_list.php
5) pages/usuarios_list.php
- Debe incluir require_once de lib/Conexion.php y lib/Functions.php
- Debe crear:
$functions = new Functions();
- Debe ejecutar un SELECT:
SELECT id,nombre,correo,rol,activo,created_at FROM usuarios ORDER BY id DESC
- Debe validar:
if ($getUsers['res'] !== 'ok') die($getUsers['res']);
- Debe mostrar tabla HTML con resultados
- Debe usar el patrón:
while ($row = $getUsers['query']->fetch_assoc()) {
foreach ($row as $key => $value) { $$key = $value; }
... imprimir $id, $nombre, $correo, $rol, $activo ...
}
6) assets/css/style.css
- Estilos mínimos para que se vea limpio.
7) assets/js/copy.js
- Script simple para copiar bloques de código (opcional, mínimo).
IMPORTANTE:
- NO incluyas CREATE DATABASE ni CREATE TABLE.
- NO incluyas INSERT/UPDATE/DELETE.
- SOLO SELECT.
Genera 10 ejercicios SOLO de SELECT para la tabla usuarios (id,nombre,correo,rol,activo,created_at),
de nivel principiante a intermedio, incluyendo:
- WHERE con activo
- ORDER BY
- LIMIT
- LIKE para nombre/correo
- AS (alias)
NO incluyas respuestas. Solo enunciados.
$getUsers['query'] y qué tipo de objeto es?fetch_assoc() y qué hace num_rows?