Contenido del curso

Encadenamiento de métodos en PHP con PDO

Resumen

¿Te imaginas escribir consultas en PHP tan legibles como las de Laravel? El encadenamiento de métodos te permite construir queries dinámicas y seguras conectando funciones como query(), get() y firstOrFail(), evitando inyección SQL y dando vida a cada publicación de tu blog.

Esta técnica es clave si estás aprendiendo PHP orientado a objetos y quieres acercarte al estilo de los frameworks modernos sin depender de uno todavía.

¿Cómo generar enlaces dinámicos a partir del ID?

Lo primero es lograr que cada publicación del home enlace a su propia vista usando el id que viene de la base de datos.

Dentro de home.template, el atributo href se construye con código PHP incrustado, apuntando a la ruta post y concatenando $post['id']. Al inspeccionar el navegador verás que cada tarjeta genera un enlace único: /post?id=6, /post?id=5, y así sucesivamente [01:00].

El problema aparece cuando el sistema de rutas mezcla el segmento post con los parámetros de la URL y devuelve un 404. Aquí entra la depuración con var_dump() para ver qué está recibiendo realmente el index.php antes de buscar la ruta.

¿Por qué usar parse_url para limpiar la URL?

PHP ofrece la función parse_url(), que adapta una cadena al formato URL y separa la ruta de los parámetros. Esto es lo que permite que el router solo evalúe /post y no /post?id=6 [01:45].

Usando la constante PHP_URL_PATH obtienes únicamente la ruta limpia. Si en algún momento necesitas los parámetros, puedes usar PHP_URL_QUERY como alternativa, dejándolo comentado para referencia futura.

¿Qué hace parse_url en PHP? Descompone una URL en sus partes (esquema, host, ruta, query). Con PHP_URL_PATH obtienes solo la ruta sin parámetros, ideal para sistemas de rutas.

Una vez aplicada esta limpieza, el sistema reconoce la ruta post y activa el controlador correspondiente.

¿Qué es el encadenamiento de métodos y cómo funciona?

El encadenamiento de métodos consiste en invocar varios métodos seguidos sobre el mismo objeto, separados por ->, gracias a que cada método retorna $this [03:30].

En el controlador home, la consulta para listar publicaciones queda así:

php $posts = $database->query('SELECT * FROM posts')->get();

En el controlador post, en cambio, necesitas una sola publicación filtrada por id. Aquí el query usa parámetros nombrados:

php $post = $database->query( 'SELECT * FROM posts WHERE id = :id', ['id' => $_GET['id']] )->firstOrFail();

La diferencia es clara: get() devuelve una colección, mientras que firstOrFail() devuelve un único registro o lanza un 404 si no existe.

¿Cuál es la diferencia entre get y firstOrFail? get() retorna todos los resultados como array usando fetchAll(). firstOrFail() retorna un solo registro con fetch() y muestra error 404 si no encuentra nada.

¿Cómo evitar inyección SQL con PDO y parámetros?

Cuando trabajas con datos que vienen del usuario, nunca debes concatenarlos dentro del método query() directamente, porque eso abre la puerta a inyección SQL.

La solución está en usar el sistema de prepared statements que ofrece PDO. Dentro de la clase Database, el método query se ajusta para aceptar dos argumentos: la sentencia y un arreglo de parámetros [04:50].

php public function query($query, $params = []) { $this->statement = $this->connection->prepare($query); $this->statement->execute($params); return $this; }

Los puntos clave de esta implementación son:

  • La propiedad $this->statement guarda la sentencia preparada para reutilizarla.
  • El execute($params) vincula los valores de forma segura, escapándolos automáticamente.
  • El return $this es lo que habilita el encadenamiento posterior con get() o firstOrFail().

¿Cómo se implementan get y firstOrFail en la clase Database?

Ambos métodos viven dentro de la misma clase y operan sobre la sentencia ya ejecutada.

php public function get() { return $this->statement->fetchAll(); }

public function firstOrFail() { $result = $this->statement->fetch(); if (!$result) { abort(); } return $result; }

La función abort() se encarga de mostrar la vista 404 cuando la consulta no devuelve resultados, lo que ocurre por ejemplo si alguien manipula el id en la URL hacia uno que no existe [06:20].

¿Cómo se conecta la vista post con la consulta dinámica?

Una vez que el controlador entrega la variable $post, la plantilla post.html se adapta para imprimir los campos correspondientes.

Los reemplazos típicos son:

  • El título estático se cambia por <?= $post['title'] ?>.
  • El contenido se reemplaza por <?= $post['body'] ?> o el campo que tengas definido.
  • El botón genérico de prueba se elimina porque ya no aplica al flujo real.

En el menú de navegación también desaparece el enlace manual hacia /post, ya que ahora ese controlador solo se invoca a través de los ids generados desde el listado. La ruta sigue registrada en el sistema porque es la que responde a las consultas dinámicas, pero no necesita estar visible para el usuario.

Prueba este patrón en tu propio blog: una clase Database con query(), get() y firstOrFail() te da consultas expresivas, seguras y reutilizables. Cuéntame en los comentarios qué otros métodos encadenarías para enriquecer tu API interna.