La Base de Datos (WPDB)
Utiliza la clase wpdb para realizar consultas SQL seguras y eficientes. Descubre cómo crear y modificar tablas personalizadas cuando la estructura nativa de WordPress es limitada.
Aunque WordPress ofrece APIs robustas como CPTs y metadatos, existen escenarios donde el volumen de información o la complejidad relacional exigen interactuar directamente con la base de datos. En este capítulo, descubriremos cómo trascender las estructuras nativas. Aprenderás a utilizar la clase global $wpdb para manipular datos, blindarás tus consultas contra inyecciones SQL usando sentencias preparadas, y dominarás dbDelta() para construir y actualizar esquemas de tablas personalizadas, estableciendo un control de versiones seguro y optimizado para el máximo rendimiento de tu plugin.
5.1 La clase global $wpdb
En el corazón de la interacción entre WordPress y su base de datos se encuentra la clase wpdb. Ubicada en el archivo wp-includes/wp-db.php, esta clase actúa como una capa de abstracción sobre la base de datos (típicamente MySQL o MariaDB). Su propósito principal es proporcionar un conjunto estandarizado de métodos para consultar, insertar, actualizar y eliminar datos sin tener que utilizar las funciones nativas de PHP como mysqli_query() o PDO directamente.
Para acceder a esta instancia única en cualquier parte de tu plugin, debes invocar la variable global:
PHP
A nivel de arquitectura, la clase $wpdb se sitúa entre la lógica de tu plugin y el motor de la base de datos, facilitando el acceso a tablas nativas y personalizadas:
TEXT
Propiedades clave del objeto $wpdb
Al invocar $wpdb, obtienes acceso a propiedades vitales que exponen información sobre la base de datos y el estado de la última consulta ejecutada:
$wpdb->prefix: El prefijo de las tablas de la base de datos (por defecto,wp_). Es imperativo usar esta propiedad en lugar de escribir el prefijo en duro al consultar tablas nativas o personalizadas para garantizar la compatibilidad en cualquier instalación.$wpdb->insert_id: Contiene el ID generado por la última consultaINSERTejecutada.$wpdb->num_rows: Devuelve el número de filas afectadas o devueltas por la última consulta.$wpdb->last_error: Almacena el mensaje de error de la última consulta que falló, fundamental para la depuración.- Tablas nativas: WordPress mapea todas sus tablas nativas como propiedades (ej.
$wpdb->posts,$wpdb->users,$wpdb->options). Usar$wpdb->postses preferible a{$wpdb->prefix}posts.
Métodos de lectura de datos
La clase ofrece métodos específicos dependiendo de la estructura de los datos que esperas recibir. Esta granularidad optimiza la memoria y simplifica el manejo de los resultados en PHP.
1. get_var()
Diseñado para recuperar un único valor (una celda específica) de la base de datos. Si la consulta devuelve múltiples filas o columnas, solo se retorna el valor de la primera columna de la primera fila.
PHP
2. get_row()
Recupera una única fila completa. Es ideal cuando buscas un registro específico basado en un ID o una condición única. Permite especificar el formato de salida: objeto (por defecto), array asociativo o array numérico.
PHP
3. get_col()
Devuelve una única columna de resultados en forma de array unidimensional. Muy útil para obtener listados de IDs o valores específicos.
PHP
4. get_results()
Es el método más versátil para recuperar múltiples filas de resultados. Al igual que get_row(), permite definir el formato de salida, siendo un array de objetos el valor predeterminado.
PHP
Métodos de conveniencia para escritura y modificación
Para operaciones de inserción, actualización y borrado, WordPress proporciona métodos "helper" que abstraen la escritura de la sentencia SQL y, crucialmente, manejan la sanitización y preparación de los tipos de datos de forma automática.
| Método | Descripción y uso recomendado |
|---|---|
insert() | Inserta una nueva fila en una tabla. Recibe la tabla, un array asociativo con los datos (columna => valor), y opcionalmente los formatos de datos (%s para string, %d para entero, %f para float). |
update() | Actualiza filas existentes. Recibe la tabla, los datos a actualizar, un array con las condiciones WHERE, y opcionalmente los formatos para los datos y las condiciones. |
delete() | Elimina filas que coinciden con condiciones específicas. Recibe la tabla, las condiciones en un array asociativo, y los formatos de las condiciones. |
Ejemplo de uso de métodos de conveniencia:
PHP
Estos métodos de conveniencia son la forma recomendada de alterar la base de datos, ya que evitan la inyección SQL en la mayoría de los casos básicos. Sin embargo, para consultas más complejas (como JOINs complejos, o métodos de lectura como get_results() que requieren variables dinámicas), será obligatorio el uso del método de preparación de sentencias, el cual se abordará en profundidad en la siguiente sección.
5.2 Consultas SQL seguras con prepare
Cuando utilizas los métodos de conveniencia descritos en la lección anterior (insert, update, delete), WordPress se encarga automáticamente de sanitizar y escapar los datos. Sin embargo, cuando necesitas ejecutar consultas complejas utilizando métodos directos como get_results(), get_var() o el método genérico query(), la responsabilidad de la seguridad recae completamente sobre ti.
La regla de oro en el desarrollo para WordPress es: nunca confíes en la entrada del usuario y nunca pases variables directamente a una cadena SQL. Hacerlo abre la puerta a ataques de Inyección SQL (SQLi), la vulnerabilidad más crítica en aplicaciones web.
Para blindar tus consultas, WordPress proporciona el método $wpdb->prepare().
El funcionamiento de prepare()
A diferencia de las sentencias preparadas nativas de extensiones como PDO (donde la consulta y los datos se envían por separado al servidor MySQL), $wpdb->prepare() actúa a nivel de PHP. Funciona de manera similar a la función sprintf() de PHP, tomando una cadena con marcadores de posición (placeholders) y sustituyéndolos por variables, pero añadiendo una capa vital: escapa y entrecomilla automáticamente los valores.
TEXT
Marcadores de posición admitidos
$wpdb->prepare() soporta un conjunto estricto de marcadores. Es crucial utilizar el correcto según el tipo de dato esperado en la base de datos:
%s(String): Para cadenas de texto, fechas, horas y cualquier dato que no sea estrictamente numérico. Nota importante:$wpdb->prepare()añade las comillas simples automáticamente. Nunca debes escribir'%s'en tu consulta.%d(Decimal/Integer): Para números enteros. Si pasas una cadena o un decimal, lo convertirá a un entero.%f(Float): Para números con decimales.%i(Identificador): Introducido en WordPress 6.2. Sirve para escapar nombres de tablas o nombres de columnas dinámicamente. Nunca debe usarse para valores de datos.
Ejemplos de implementación
1. El antipatrón (Inseguro)
Nunca debes interpolar variables directamente en la cadena, incluso si crees que están sanitizadas previamente.
PHP
2. La forma correcta
Utiliza $wpdb->prepare(). Puedes pasar los argumentos secuencialmente o como un array.
PHP
El desafío de las cláusulas LIKE
Un error muy común ocurre al intentar usar sentencias LIKE para búsquedas, ya que el carácter comodín % entra en conflicto con la sintaxis de los marcadores de posición de prepare().
Para resolver esto, WordPress dispone del método de ayuda $wpdb->esc_like(). Este método escapa específicamente los caracteres con significado especial en SQL (% y _) dentro de la cadena de búsqueda antes de que la pases a prepare().
PHP
Uso de %i para identificadores dinámicos
Antes de WordPress 6.2, si necesitabas construir una consulta donde el nombre de la tabla o la columna dependía de una variable, no podías usar prepare() para esos elementos y debías recurrir a la función sanitize_key() y concatenación estricta. Ahora, con el marcador %i, es mucho más limpio:
PHP
Al dominar $wpdb->prepare(), garantizas que cualquier interacción compleja de lectura o escritura que tu plugin requiera estará protegida desde su concepción, cumpliendo con los estándares de seguridad requeridos por el repositorio oficial de WordPress.
5.3 Creación de tablas con dbDelta
Cuando los Custom Post Types, las taxonomías o la Metadata API nativa de WordPress no son suficientes para cubrir los requisitos de rendimiento o estructura de tu plugin, se hace necesario crear tablas personalizadas en la base de datos. Para realizar esta tarea de forma segura y estandarizada, WordPress proporciona la función dbDelta().
Ubicada en wp-admin/includes/upgrade.php, dbDelta() es una herramienta que examina la estructura actual de la base de datos, la compara con la estructura declarada en tu código y realiza selectivamente los cambios necesarios (como añadir nuevas columnas o modificar tipos de datos) sin alterar ni borrar la información existente.
El flujo operativo de la función se puede representar de la siguiente manera:
TEXT
Las reglas estrictas de sintaxis de dbDelta()
La función dbDelta() es sumamente selectiva y sensible a la sintaxis del esquema SQL que recibe. Si no se respetan de manera estricta sus reglas de formateo, la función fallará silenciosamente, no creará la tabla o recreará la estructura en cada ejecución, afectando severamente el rendimiento.
Para que dbDelta() procese correctamente tu sentencia CREATE TABLE, debes cumplir los siguientes requisitos:
- Un elemento por línea: Debes colocar cada definición de columna y cada declaración de clave en su propia línea dentro del bloque SQL.
- Dos espacios en PRIMARY KEY: Debe haber exactamente dos espacios entre las palabras clave
PRIMARY KEYy la definición del campo entre paréntesis:PRIMARY KEY (id). Un solo espacio romperá el analizador sintáctico interno de la función. - Dos espacios en índices convencionales: Al declarar un índice ordinario, debes usar la palabra clave
KEYen lugar deINDEX, seguida de dos espacios, el nombre del índice, otros dos espacios y la columna afectada:KEY mi_indice (columna). - Tipos de datos en minúsculas: Los tipos de datos de SQL (como
int,bigint,varchar,text,datetime) deben escribirse estrictamente en minúsculas. - Sin acentos graves (backticks): No utilices el carácter de acento grave (```) para envolver los nombres de las tablas o de las columnas, práctica común en exportaciones directas de phpMyAdmin.
- Longitudes explícitas: Especifica siempre la longitud de los campos de texto ajustables, por ejemplo,
varchar(255).
Implementación práctica en la activación del plugin
El momento idóneo para crear o actualizar el esquema de base de datos de un plugin es durante su rutina de activación, utilizando el hook register_activation_hook().
A continuación se detalla una implementación profesional que incorpora el juego de caracteres nativo del sitio mediante $wpdb->get_charset_collate() para asegurar la compatibilidad idiomática de los datos almacenados:
PHP
Verificación de la creación de la tabla
Para validar si dbDelta() completó correctamente la operación, puedes inspeccionar el arreglo que retorna la función o verificar directamente la propiedad $wpdb->last_error inmediatamente después de la llamada:
PHP
El valor devuelto por dbDelta() es un array asociativo donde las llaves son los nombres de las tablas y los valores contienen cadenas de texto descriptivas con las acciones exactas realizadas (por ejemplo, "Created table $nombre_tabla" o "Added column $nombre_tabla.nueva_columna"). Si la estructura de la base de datos ya coincide plenamente con la consulta provista, el array retornado estará vacío, garantizando que no se consumieron recursos innecesarios del servidor MySQL.
5.4 Actualización de esquemas de datos
A medida que tu plugin evoluciona y se publican nuevas versiones, es altamente probable que las tablas personalizadas que creaste en versiones iniciales requieran modificaciones: añadir una nueva columna, modificar el tipo de dato de un campo existente o incorporar un nuevo índice para optimizar consultas.
Como vimos en la lección anterior, la función dbDelta() es destructivamente segura; es decir, altera la estructura existente sin purgar los datos. Sin embargo, procesar dbDelta() es una operación costosa a nivel de rendimiento. Si ejecutas la rutina de actualización en cada carga de página o incluso en cada inicialización del panel de administración, el tiempo de respuesta de WordPress se verá severamente degradado.
La solución arquitectónica estándar en WordPress es implementar un sistema de control de versiones de la base de datos.
El flujo de actualización basado en versiones
El concepto fundamental radica en definir la versión de la estructura de base de datos actual en el código fuente de tu plugin y compararla con la versión almacenada en la base de datos (utilizando la Options API). Solo si la versión del código es superior a la guardada en la base de datos, se dispara la rutina de actualización.
TEXT
Implementación del sistema de control de versiones
Para materializar esta lógica, necesitas establecer una constante global (o propiedad de clase) que defina la versión del esquema, y una rutina anclada al hook plugins_loaded que realice la comprobación de forma temprana en el ciclo de vida de WordPress.
A continuación, se detalla una estructura profesional para gestionar este proceso:
PHP
Manejo de actualizaciones complejas (Migraciones)
Aunque dbDelta() es excelente para gestionar columnas e índices, hay operaciones estructurales que no puede resolver automáticamente, como:
- Renombrar una columna existente.
- Eliminar una columna (Drop column).
- Migrar o transformar datos de una tabla a otra.
Para estos casos excepcionales donde dbDelta() no es suficiente, tu rutina de comprobación de versiones debe ejecutar sentencias SQL directas utilizando $wpdb->query(). Es vital segmentar estas operaciones por versión para asegurar que un usuario que actualiza desde la versión 1.0 hasta la 3.0 pase por todos los pasos intermedios secuencialmente:
PHP
Implementar este patrón garantiza que las tablas de tu plugin estén siempre sincronizadas con la lógica del código de manera predecible, automatizada y respetando los recursos de la instalación de WordPress del usuario.
Resumen del capítulo
En este capítulo hemos profundizado en la capa de persistencia de datos de WordPress, dominando las herramientas que el núcleo ofrece para interactuar con la base de datos sin comprometer la seguridad ni la estabilidad de la plataforma:
- La clase
$wpdb: Comprendimos cómo esta instancia global actúa como interfaz de comunicación, ofreciendo métodos eficientes (get_var,get_results,insert,update) para manipular información. - Consultas Seguras: Adoptamos el uso estricto de
$wpdb->prepare()para sanitizar, escapar y blindar cualquier variable dinámica frente a ataques de inyección SQL, incluyendo el uso deesc_likey comodines dinámicos. - Creación de Esquemas: Exploramos
dbDelta()y sus rígidas reglas sintácticas para construir y desplegar tablas personalizadas de forma no destructiva durante la activación del plugin. - Mantenimiento y Control de Versiones: Establecimos una arquitectura basada en
plugins_loadedy la Options API para actualizar las estructuras de datos de manera silenciosa, secuencial y óptima para el rendimiento del servidor en cada nueva versión del plugin.
© 2026 Esdocu. Contenido bajo licencia MIT.
Editar esta página