Accediendo a una base de datos externa usando la clase wpdb en WordPress

7 minutos de lectura

avatar de usuario
Gonrás Karols

Tengo una plantilla de página personalizada en WordPress que se basa en una base de datos externa y que usa la clase wpdb para este propósito.

Este es mi código:

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header">
        <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
    </header><!-- .entry-header -->

<?php

class StudentsDatabase
{
    private $db;
    public function __construct() {
        try {
            $this->db = new wpdb(DB_USER, DB_PASSWORD, 'students_db', DB_HOST);
            $this->db->show_errors();
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }
    public function getStudentById($student_id)
    {
        return $this->db->get_results("SELECT * FROM `students` WHERE id=$student_id");
    }
    public function getSchoolByAreaCode($area_code)
    {
        return $this->db->get_results("SELECT * FROM `schools` WHERE area_code=$area_code;--");
    }

}
$Students_DB = new StudentsDatabase();
$student_one = $Students_DB->getStudentById(1);
$school_one = $Students_DB->getSchoolByAreaCode(1);

?>
<div class="entry-content">
    <?php

    //do something with $student_one and $school_one ...

    the_content();

    ?>
</div><!-- .entry-content -->

Bueno, me preguntaba si esta es la forma correcta de hacerlo. En cuanto a la seguridad o cualquier ‘otro’-sabio en realidad.

Se siente un poco incompleto hacer llamadas externas a la base de datos desde la propia plantilla de la página. ¿Debo registrar estas funciones en algún archivo externo y luego usarlas dentro de la plantilla?

  • ¿Puedo ingresar esto como un valor para area_code o student_id? “null or 1=1; drop table users; --” Asegúrese de que las entradas estén ‘desinfectadas’ antes mesas bobby pone sus manos en su página.

    – codificador

    30 de mayo de 2017 a las 23:56

  • @thenaglecode están todos bien desinfectados, acabo de publicar parte del código (: ¡pero gracias por la preocupación!

    – Gonrás Karols

    31 de mayo de 2017 a las 12:27

Creo que la forma más “limpia” es implementar un complemento que sea una API para su tema. Por supuesto, depende si es un tema solo para sus propios fines porque WordPress (hasta ahora) carece de un administrador de dependencias.

Para resumir, en el tema, use esta API.

  • Realmente no entendí tu resumen. De todos modos, este método se utilizará en cientos de sitios web diferentes: cada uno de ellos tiene un tema diferente y personalizaciones propias específicas. Entonces, un complemento no es una solución en este caso … requeriría mucho tiempo y trabajo para cubrir todos estos casos.

    – Gonrás Karols

    2 de junio de 2017 a las 16:02

  • Esta no es la respuesta más elegante, pero es 100 correcta. Si la pregunta es cómo accedo a una base de datos externa, la respuesta es a través de una API. La muestra de código del OP es un galimatías, ¡así que esta es una gran respuesta!

    –Jim Maguire

    4 de junio de 2017 a las 8:06

  • @GonrasKarols – tiene un tema diferente y personalizaciones propias específicas – es por eso que debería ser un complemento; El complemento comparte una lógica común de manera abstracta: cuando corrige un error, simplemente actualiza un complemento, no reemplaza cada instancia de código.

    – eRIZ

    5 de junio de 2017 a las 8:17

  • @eRIZ ¿Qué quiere decir con “un complemento que sería una API para su tema”? ¿Mi plantilla custom-page.php necesita hacer llamadas API al complemento o al revés? ¿El complemento entregará información de la base de datos en las secciones correctas en custom-page.php? siento que me falta algo..

    – Gonrás Karols

    5 de junio de 2017 a las 19:10

  • Su complemento proporciona, por ejemplo, un método llamado my_vendor_get_poll_data devolviendo una matriz. Usas esta función dentro de tu tema y solo envolver datos allí. Deje cualquier procesamiento a su complemento.

    – eRIZ

    6 jun 2017 a las 12:50

Pon el class declaraciones, etc. en el funciones.php archivo del tema. O mejor, require_once allí, y ponerlos en un assets o includes carpeta del tema.

-/theme/
   -/includes/classes/class-studentsDatabase.php
   -functions.php

En funciones.php

define('TEMPLATE_PATH', get_template_directory());
require_once(TEMPLATE_PATH . '/includes/classes/class-studentsDatabase.php');

Puede instanciar el class(es) para el tema en su conjunto, o según sea necesario en la(s) página(s) de la plantilla como lo está haciendo ahora.


En lo que respecta a la seguridad, evitaría colocar conexiones de base de datos que deben ser seguras dentro de un tema que se va a enviar a la naturaleza.

No estoy seguro de seguir lo que estás haciendo con ese fin, pero tal como se presenta, manejaría esa parte fuera del entorno del tema.

Nuevamente, sin conocer su caso de uso, el tema podría aprovechar una API externa, y esa API podría ser una API de wordpress wp-json que administra esa conexión de base de datos en un sitio central.

Eso permitiría que el tema GET / POST a un punto final que maneja la autenticación y cualquier CRUD, y mitiga una gran cantidad de posibles problemas de seguridad. El tema en el sitio externo simplemente estaría analizando el json devuelto y no tendría ningún acceso a la base de datos más allá de eso.

  • Este es un error común entre los desarrolladores principiantes de WP. Si está agregando funcionalidad, debe ir en un complemento, no en un tema. Si está modificando el “aspecto” de un sitio, debe ir en functions.php de su tema. Este tipo de cosas absolutamente no deberían ponerse en un tema.

    –Jim Maguire

    4 de junio de 2017 a las 8:04

  • @JimMaguire Si crea una funcionalidad relacionada con un tema específico, ¿por qué no ponerla dentro del tema functions.php? Un tema en wordpress es mucho más que un “tema” que define el aspecto del sitio. (Al menos esto es lo que resultó ser en los últimos 2-3 años)

    – Avishay28

    04/06/2017 a las 19:53

  • Es difícil pensar en un ejemplo en el que lo que estás sugiriendo tenga sentido. Sí… por supuesto que los vendedores de temas ponen funcionalidad en un tema, quieren encerrarte y venderte algo. Te preguntaría ¿por qué ponerlo en un tema? Limita tus opciones y no gana nada.

    –Jim Maguire

    6 de junio de 2017 a las 0:44


  • Al volver a leerlo, tengo que ponerme del lado de Jim en esto. Estaba comentando sobre la separación de las declaraciones de clase y sus métodos de los archivos de plantilla, y no fui lo suficientemente directo en mis comentarios sobre el bit de conexión de la base de datos de OP. El enfoque es un error y debe ser rediseñado. Mi “el tema podría aprovechar una API externa” debería tener “a través de un complemento” adjunto. Cualquiera que sea la funcionalidad que pueda requerir el tema, debe relegarse a la entrega de los archivos de plantilla. Si OP está tratando de crear y administrar una relación Servidor-> Cliente a través de un tema, no está pidiendo nada más que dolores de cabeza.

    – grito

    6 de junio de 2017 a las 2:42

  • No estaba hablando de administrar las relaciones servidor-cliente a través de un tema; solo necesito algunas declaraciones get_results() simples que se vincularían a una base de datos externa y los resultados afectarían el contenido de la página. Nada demasiado complicado y solo se requiere una comunicación unidireccional (de db a la plantilla). Entonces, ¿lo que está diciendo es que debería crear un complemento que maneje la conexión db y las consultas, y envíe datos a la plantilla en sí?

    – Gonrás Karols

    6 de junio de 2017 a las 8:01

También hay una forma más radical de trabajar con múltiples bases de datos en WordPress. Como sigue de wpdb página del códice:

El objeto $wpdb puede comunicarse con cualquier cantidad de tablas, pero solo con una base de datos a la vez; por defecto la base de datos de WordPress. En el raro caso de que necesite conectarse a otra base de datos, deberá crear una instancia de su propio objeto de la clase wpdb con su propia información de conexión a la base de datos. Para configuraciones extremadamente complicadas con muchas bases de datos, considere usar hyperdb en su lugar.

hiperdb es un complemento que ayuda con múltiples bases de datos y reemplaza su pensamiento excesivo sobre la organización del código.

¿Ha sido útil esta solución?