php WordPress

Utiliza Namespaces cuando desarrolles un plugin

En este post vamos a ver qué son, y cómo y porqué deberías utilizar Namespaces cuando desarrolles algo, por ejemplo, un plugin para WordPress.

Los Namespaces o espacios de nombres, están presentes en muchos lenguajes de programación. En PHP, están disponibles desde la versión 5.3 y en la propia documentación podemos encontrar su definición:

Los espacios de nombres son una manera de encapsular elementos. Se pueden ver como un concepto abstracto en muchos aspectos. Por ejemplo, en cualquier sistema operativo, los directorios sirven para agrupar ficheros relacionados, actuando así como espacios de nombres para los ficheros que contienen. Como ejemplo, el fichero foo.txt puede existir en los directorios /home/greg y /home/otro, pero no pueden coexistir dos copias de foo.txt en el mismo directorio. Además, para acceder al fichero foo.txt fuera del directorio /home/greg, se debe anteponer el nombre del directorio al nombre del fichero, empleando el separador de directorios para así obtener /home/greg/foo.txt. Este mismo principio se extiende a los espacios de nombres en el mundo de la programación.

Documentación oficial de PHP

Es decir, nos van a permitir una mejor organización de nuestro código y además evitarán posibles colisiones con clases y métodos de, por ejemplo, otro plugin o tema.

¿Por qué es aconsejable el uso de Namespaces?

Cuando desarrollamos sobre WordPress, debemos tener en cuenta que para nuestro proyecto van a coexistir clases y funciones que provienen de:

  • El propio WordPress
  • El tema que tengamos activo
  • Los muchos o pocos plugins que tengamos activos

De hecho, hace años era bastante normal encontrarse con que dos plugins eran incompatibles entre sí, una cosa que irritaba bastante a algunos, llegando a afirmar que la incompatibilidad entre plugins era de lo peor de WordPress.

¡Más de dos años he estado sin poder utilizar el plugin de SEO by Yoast por incompatibilidad por otros plugins! Qué horror. Cada vez que intentaba instalarlo se me iba al traste toda la web, no podía ver las entradas ni las categorías. Y no es la única incompatibilidad entre plugins que me he encontrado en los años que llevo trabajando con WordPress.

OMG…

Muchos de estos problemas probablemente hubieran sido solucionados utilizando Namespaces, o mediante alguna alternativa como utilizar prefijos para todo como se recomienda desde la guía de buenas prácticas.

Su uso, además de permitir organizar, estructurar y democratizar mejor nuestro trabajo, evitará colisiones con plugins y/o temas de terceros. Y mejorará nuestra reputación, que algunos a la mínima oportunidad nos desprestigian y ponen en el centro del mal.

Y a través de ellos, ya no tendremos que hacer includes o requires, nuestro desarrollo será un poco más elegante.

¿Cómo utilizar Namespaces para nuestros desarrollos en WordPress?

Afortunadamente, a través de composer, es muy sencillo. En la raíz de nuestro plugin crearemos el fichero composer.json con el siguiente contenido:

{
  "name": "my plugin name",
  "description": "my plugin description",
  "require": {
    "php": ">=7.3"
  },
  "autoload": {
    "psr-4": {
      "Mynamespace\\": "includes/"
    }
  }
}

Una vez tengamos esto, bastará con ejecutar composer install, y se nos creará una carpeta vendor con todo lo necesario. Para poder hacer uso del autoload de Namespaces en nuestro plugin, bastará con incluirlo en el archivo php principal de nuestro plugin:

require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';

Ahora podremos llamar a todas las clases de nuestro sitio (que se encuentren en la carpeta includes) a través de namespaces.

Consideraciones a tener en cuenta para el uso de namespaces

Cuando crees una clase y declares el namespace, este debe ser declarado en la parte superior del archivo, justo después de las etiquetas de apertura de PHP. Debe ser el primer comando y no puede haber ningún código PHP que lo preceda, excepto declare (si lo utilizas).

Ejemplo: Imagina que tienes una pequeña clase Settings, dentro de la carpeta Admin, que a su vez está dentro de includes (my-plugin/includes/Admin/Settings.php), el archivo sería algo tipo:

<?php declare( strict_types = 1 );

namespace Mynamespace\Admin;

// Exit if accessed directly
defined( 'WPINC' ) or die( 'No script kiddies please!' );

/**
 * Class Settings
 */
class Settings {
    // Code
}

Lo primero a declarar es nuestro namespace Mynamespace\Admin. Únicamente podremos poner por encima una sentencia declare.

¿Y cómo hacemos uso de esta clase? Pues tenemos dos formas. Lo que ya no es necesario es andar haciendo includes o requires. Vamos a ver estas dos formas mediante un ejemplo. Imaginemos que en nuestra clase Settings tenemos un método estático que nos devuelve un option.

La primera forma es llamando al namespace directamente:

<?php declare( strict_types = 1 );

namespace Mynamespace\Wpo;

// Exit if accessed directly
defined( 'WPINC' ) or die( 'No script kiddies please!' );

/**
 * Class Assets
 */
class Assets {
    public function my_method() {
        $my_option = Mynamespace\Admin\Settings::get_my_option();
        // code
    }
}

La segunda es declarar un use en el archivo donde vayamos a llamar a este método, justo debajo del namespace de este otro archivo:

<?php declare( strict_types = 1 );

namespace Mynamespace\Wpo;

use Mynamespace\Admin\Settings;

// Exit if accessed directly
defined( 'WPINC' ) or die( 'No script kiddies please!' );

/**
 * Class Assets
 */
class Assets {
    public function my_method() {
        $my_option = Settings::get_my_option();
        // code
    }
}

Como ves, bastante sencillo y bastante útil. Y más elegante y legible que poner un prefijo para todo.

¿Te ha resultado útil esta información? 🍺

Si este post te ha resuelto un problema, invítame a un café o a una cerveza. Con este pequeño gesto me animas a seguir escribiendo.

Comentarios

2 comentarios en Utiliza Namespaces cuando desarrolles un plugin

    1. Entiendo que lo dices para que genere la carpeta «vendor» con las dependencias que necesites. Creo que es mejor opción distribuir el plugin con la carpeta vendor directamente.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *:

  • El fin del tratamiento es únicamente la moderación de comentarios para evitar spam
  • La legitimación es tu consentimiento al comentar
  • No se comunicará ningún dato a terceros salvo por obligación legal
  • Tienes derecho al acceso, rectificación y eliminación de los comentarios