Wordpress

Consultas en WordPress utilizando $wpdb

Consultas en WordPress utilizando $wpdb

Wordpress

La forma establecida para operar en la base de datos de WordPress es utilizando $wpdb.

Motivos para utilizar wpdb

Aunque WordPress está creado en PHP y se podrían utilizar los métodos propios de este lenguaje para realizar consultas a la base de datos, no es la forma recomendable de hacerlo por las siguientes razones:

  • La clase wpdb proporciona mejoras de seguridad y protección contra inyección o ataques de tipo SQL.
  • En una posible migración o cambio de motor de base de datos, podrían no funcionar.

Clase wpdb

Existe una clase llamada wpdb definida en /wp-includes/wp-db.php. Por defecto, WordPress ya carga en las variables globales una llamada $wpdb, para que podamos accedera a ella y realizar las consultas que necesitemos.

Si creamos un método o función, no debemos olvidarnos de cargarla:

global $wpdb;

Este objeto no está limitado a las tablas propias de WordPress, sinó que se puede utilizar para trabajar con tablas propias o las creadas por un módulo, etc.

Código de ejemplo

Para explicarlo correctamente, creamos un fichero php con una clase llamada myConfiguration, en la que crearemos métodos para operar con la base de datos. El código completo es el siguiente, y la explicación la haremos más abajo.

<?php 
/* Requerido */
require_once(explode("wp-content", __FILE__)[0] . "wp-load.php");


class myConfiguration{

        private $my_table = "";

        public function __construct(){
                global $wpdb;
                $this->my_table = $wpdb->prefix . 'my_configuration';
        }


        /*
        * Create table if not exists
        */
        public function createTable(){
                global $wpdb;

                $sql = 'CREATE TABLE IF NOT EXISTS `' . $this->my_table . '` ( `id` INT NOT NULL AUTO_INCREMENT, `name` TEXT NOT NULL, `value` TEXT NOT NULL, `date_update` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`)); ';

                if(!$wpdb->query($sql)) return false;
                return true;

        }


        /*
        * Insert configuration
        */
        public function set($name, $value){
                global $wpdb;

                return $wpdb->insert( 
                        $this->my_table, 
                        array( 
                                'name' => $name, 
                                'value' => $value
                        ), 
                        array( 
                                '%s', 
                                '%s'
                        ) 
                );

        }


        /*
        * Get all names
        */
        public function getNames(){
                global $wpdb;
              
                $sql = 'SELECT value FROM `' . $this->my_table . '`;';
                return $wpdb->get_results($wpdb->prepare($sql));

        }


        /*
        * Get value by name
        */
        public function getValue($name){
                global $wpdb;
                /* 
                si en el select ponemos * -> traerá el primer id
                si en el select ponemos un campo -> traerá el primer valro de ese campo
                si en el where ponemos, por ejemplo, name = 'LANGUAGE', traerá la primera fila que encuentre con ese name
                */
                $sql = 'SELECT value FROM `' . $this->my_table . '` WHERE name="' . $name . '";';
                return $wpdb->get_var($wpdb->prepare($sql));

        }


        /*
        * Update configuration by name
        */
        public function update($name, $value){
                global $wpdb;

                return $wpdb->update( 
                        $this->my_table, 
                        array( 
                                'value' => $value
                        ), 
                        array( 
                                'name' => $name
                        ) 
                );

        }


        /*
        * Delete configuration
        */
        public function delete($name){
                global $wpdb;

                return $wpdb->delete( 
                        $this->my_table, 
                        array( 
                                'name' => $name
                        ) 
                );

        }


        /*
        * Delete table
        */
        public function deleteTable(){
                global $wpdb;

                $sql = 'DROP TABLE `' . $this->my_table . '`;';
                if(!$wpdb->query($sql)) return false;
                return true;

        }


}

Crear tabla en WordPress

Crearemos una tabla para realizar las pruebas.

$my_conf_obj = new myConfiguration();
$result = $my_conf_obj->createTable();
var_dump($result); // bool(true)

Llamamos al método createTable(), que hace lo siquiente:

 public function createTable(){
                global $wpdb;

                $sql = 'CREATE TABLE IF NOT EXISTS `' . $this->my_table . '` ( `id` INT NOT NULL AUTO_INCREMENT, `name` TEXT NOT NULL, `value` TEXT NOT NULL, `date_update` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`)); ';

                if(!$wpdb->query($sql)) return false;
                return true;

        }

El atributo my_table está definido en la clase y asignado en el constructor. Utilizamos esta forma para evitarnos repetir constantemente el nombre de la tabla.

En el constructor, utilizamos $wpdb->prefix para conocer el prefijo de la base de datos, ya que si lo ponemos de forma estática, no nos valdrá para todas las instalaciones de WordPress.

Insertar registros en la tabla

Vamos a crear dos registros en este ejemplo. La estructura de la tabla está pensada para almacenar configuraciones, con estructura clave-valor.

$result = $my_conf_obj->set('LANGUAGE', 'EN-en');
var_dump($result); // int(1) si existe y si no existe

$result = $my_conf_obj->set('COUNTRY', 'FRANCE');
var_dump($result); // int(1) si existe y si no existe

Para ello, hemos creado el método set():

public function set($name, $value){
                global $wpdb;

                return $wpdb->insert( 
                        $this->my_table, 
                        array( 
                                'name' => $name, 
                                'value' => $value
                        ), 
                        array( 
                                '%s', 
                                '%s'
                        ) 
                );
        }

Utilizamos el método insert de la clase wpdb. Siempre devolverá un entero con valor 1.

El primer parámetro es el nombre de la tabla. El segundo parámetro es un array asociativo con las posiciones clave-valor. El tercer array, es opcional pero recomendable, especifica el tipo de dato. Por ejemplo, (%s) para string y (%d) para numéricos.

Seleccionar registros en la tabla

Para seleccionar los valores que hemos creado en la base de datos, lo haremos de la siguiente forma.

$result = $my_conf_obj->getNames();
var_dump($result); // array(2) { [0]=> object(stdClass)#14033 (1) { ["value"]=> string(5) "EN-en" } [1]=> object(stdClass)#14023 (1) { ["value"]=> string(6) "FRANCE" } }

El método que hemos creado, getNames(), es el siguiente:

 public function getNames(){
                global $wpdb;
          
                $sql = 'SELECT value FROM `' . $this->my_table . '`;';
                return $wpdb->get_results($wpdb->prepare($sql));

        }

Para buscar datos, utilizamos el método get_results de la clase wpdb. Además, el método prepare para evitar la inyección de sql.

Filtrar registros en la tabla

Para filtrar valores los valores que hemos creado en la base de datos, lo haremos de la siguiente forma.

$result = $my_conf_obj->getValue('LANGUAGE');
var_dump($result); // string(5) "EN-en" si existe, NULL si no existe

El método getValue() que hemos creado, es el siguiente:

public function getValue($name){
                global $wpdb;
                
                $sql = 'SELECT value FROM `' . $this->my_table . '` WHERE name="' . $name . '";';
                return $wpdb->get_var($wpdb->prepare($sql));

        }

Para buscar un valor, le pasamos como parámetro el nombre de la configuración que queremos consultar.

Si sólo queremos devolver un campo, es necesario elegir uno en el select y utilizar el método get_var de la clase wpdb. Además, por seguridad y al igual que en el ejemplo anterior, utilizamos el método prepare de la misma clase.

Si en el select ponemos *, nos devolverá el valor del id por ser la primera columna.

Actualizar un registro con wpdb en WordPress

El método creado en nuestra clase para este ejemplo es el update() y lo utilizamos así:

$result = $my_conf_obj->update('LANGUAGE', 'ES-es');
var_dump($result); // int(1) si existe, int(0) si no existe

El código de nuestro método, es el siguiente:

public function update($name, $value){
                global $wpdb;

                return $wpdb->update( 
                        $this->my_table, 
                        array( 
                                'value' => $value
                        ), 
                        array( 
                                'name' => $name
                        ) 
                );

        }

Utilizamos el método update de la clase wpdb, y le pasamos tres parámetros. El primero es el nombre de la tabla. El segundo un array asociativo de clave-valor con los datos a actualizar. El tercero, es otro array asociativo, equivalente a la condición del where.

Eliminar un registro

Para eliminar un registro utilizando nuestra clase, lo haermos de la siguiente forma:

$result = $my_conf_obj->delete('LANGUAGE');
var_dump($result); // int(1) si existe, int(0) si no existe

El código de nuestro método delete() es este:

public function delete($name){
                global $wpdb;

                return $wpdb->delete( 
                        $this->my_table, 
                        array( 
                                'name' => $name
                        ) 
                );

        }

La clase wpdb tiene un método delete en el que deberemos pasar dos parámetros: el primero es el nombre de la tabla y el segundo es un array asociativo equivalente al where.

Eliminar una tabla

Finalmente, en nuestro ejemplo eliminaremos la tabla que hemos creado para realizar estas pruebas.

$result = $my_conf_obj->deleteTable();
var_dump($result); // bool(true)  si existe, bool(false) si no existe

El código del método deleteTable() es el que sigue:

public function deleteTable(){
                global $wpdb;

                $sql = 'DROP TABLE `' . $this->my_table . '`;';
                if(!$wpdb->query($sql)) return false;
                return true;

        }

En este caso, utilizamos el método query de la clase wpdb de WordPress.

Debug

Para mostrar los errores: $wpdb->show_errors()

Para mostrar la última consulta: $wpdb->last_query

Métodos de la clase wpdb

Aunque hemos utilizando algunos métodos en los ejemplos anteriores, existen algunos más. A continuación se listan los más utilizados.

  • get_var()
  • get_row()
  • get_col()
  • ge_results()
  • insert()
  • replace()
  • update()
  • delete()
  • query()
  • prepare()

Más información

En la documentación oficial de WordPress podremos encontrar más información relacionada con esta clase y sus métodos: https://developer.wordpress.org/reference/classes/wpdb/

Esta clase y métodos nos pueden resultar útiles para desarrollar un plugin u otra solución software para WordPress.

Leave a reply