Mejorar el código de WordPress con PHP moderno

Publicado: 2022-03-10
Resumen rápido ↬ Debido a la compatibilidad con versiones anteriores, WordPress no ha aprovechado las nuevas funciones de PHP lanzadas después de PHP 5.2.4. Afortunadamente, WordPress pronto requerirá PHP 5.6+ e incluso PHP 7.0+ no mucho después. Este artículo hace un recorrido por las funciones de PHP recientemente disponibles para WordPress e intenta sugerir cómo se pueden usar para producir un mejor software.

WordPress nació hace quince años y, debido a que históricamente ha conservado la compatibilidad con versiones anteriores, las versiones más nuevas de su código no podían aprovechar al máximo las capacidades más recientes que ofrecen las versiones más recientes de PHP. Si bien la última versión de PHP es 7.3.2, WordPress aún ofrece soporte hasta PHP 5.2.4.

¡Pero esos días pronto terminarán! WordPress actualizará su compatibilidad con la versión mínima de PHP, llegando a PHP 5.6 en abril de 2019 y a PHP 7 en diciembre de 2019 (si todo sale según lo planeado). Entonces finalmente podemos comenzar a usar las capacidades de programación imperativas de PHP sin temor a romper los sitios de nuestros clientes. ¡Viva!

Debido a que los quince años de código funcional de WordPress han influido en la forma en que los desarrolladores han creado con WordPress, nuestros sitios, temas y complementos pueden estar llenos de código menos que óptimo que con gusto puede recibir una actualización.

Este artículo se compone de dos partes:

  1. Novedades más relevantes
    Se han agregado funciones adicionales a las versiones de PHP 5.3, 5.4, 5.5, 5.6 y 7.0 (observe que no hay PHP 6) y exploraremos las más relevantes.
  2. Construyendo un mejor software
    Echaremos un vistazo más de cerca a estas características y cómo pueden ayudarnos a construir un mejor software.

Empecemos explorando las “nuevas” funciones de PHP.

¡Más después del salto! Continúe leyendo a continuación ↓

Clases, OOP, SOLID y patrones de diseño

Se agregaron clases y objetos a PHP 5, por lo que WordPress ya hace uso de estas características, sin embargo, no de manera muy amplia o completa: el paradigma de la codificación en WordPress es principalmente programación funcional (realizar cálculos llamando a funciones desprovistas del estado de la aplicación) en lugar de objeto -Programación orientada (POO) (realización de cálculos manipulando el estado de los objetos). Por lo tanto, también describo clases y objetos y cómo usarlos a través de OOP.

OOP es ideal para producir aplicaciones modulares: las clases permiten la creación de componentes, cada uno de los cuales puede implementar una funcionalidad específica e interactuar con otros componentes, y puede proporcionar personalización a través de sus propiedades encapsuladas y herencia, lo que permite un alto grado de reutilización del código. Como consecuencia, la aplicación es más económica de probar y mantener, ya que las características individuales pueden aislarse de la aplicación y tratarse por sí solas; también hay un aumento de la productividad ya que el desarrollador puede utilizar componentes ya desarrollados y evitar tener que reinventar la rueda para cada aplicación.

Una clase tiene propiedades y funciones, a las que se les puede dar visibilidad usando private (accesible solo desde dentro de la clase que la define), protected (accesible desde dentro de la clase que la define y su ancestro y las clases heredadas) y public (accesible desde cualquier lugar). Desde dentro de una función, podemos acceder a las propiedades de la clase anteponiendo sus nombres con $this-> :

 class Person { protected $name; public function __construct($name) { $this->name = $name; } public function getIntroduction() { return sprintf( __('My name is %s'), $this->name ); } }

Una clase se instancia en un objeto a través de la new palabra clave, después de lo cual podemos acceder a sus propiedades y funciones a través de -> :

 $person = new Person('Pedro'); echo $person->getIntroduction(); // This prints "My name is Pedro"

Una clase heredada puede anular las funciones public y protected de sus clases antecesoras y acceder a las funciones antecesoras anteponiéndolas con parent:: :

 class WorkerPerson extends Person { protected $occupation; public function __construct($name, $occupation) { parent::__construct($name); $this->occupation = $occupation; } public function getIntroduction() { return sprintf( __('%s and my occupation is %s'), parent::getIntroduction(), $this->occupation ); } } $worker = new WorkerPerson('Pedro', 'web development'); echo $worker->getIntroduction(); // This prints "My name is Pedro and my occupation is web development"

Un método puede hacerse abstract , lo que significa que debe ser implementado por una clase heredada. Una clase que contiene un método abstract debe volverse abstract , lo que significa que no puede instanciarse; solo se puede instanciar la clase que implementa el método abstracto:

 abstract class Person { abstract public function getName(); public function getIntroduction() { return sprintf( __('My name is %s'), $this->getName() ); } } // Person cannot be instantiated class Manuel extends Person { public function getName() { return 'Manuel'; } } // Manuel can be instantiated $manuel = new Manuel();

Las clases también pueden definir métodos y propiedades static , que viven bajo la clase misma y no bajo una instanciación de la clase como objeto. A estos se accede a través de self:: desde dentro de la clase, y a través del nombre de la clase + :: desde fuera de ella:

 class Factory { protected static $instances = []; public static function registerInstance($handle, $instance) { self::$instances[$handle] = $instance; } public static function getInstance($handle) { return self::$instances[$handle]; } } $engine = Factory::getInstance('Engine');

Para aprovechar al máximo la programación orientada a objetos, podemos utilizar los principios SOLID para establecer una base sólida pero fácilmente personalizable para la aplicación y patrones de diseño para resolver problemas específicos de una manera comprobada. Los patrones de diseño están estandarizados y bien documentados, lo que permite a los desarrolladores comprender cómo se relacionan entre sí los diferentes componentes de la aplicación y proporcionan una forma de estructurar la aplicación de manera ordenada, lo que ayuda a evitar el uso de variables globales (como global $wpdb ). que contaminan el medio ambiente mundial.

Espacios de nombres

Los espacios de nombres se agregaron a PHP 5.3, por lo que actualmente no se encuentran en el núcleo de WordPress.

Los espacios de nombres permiten organizar la base de código estructuralmente para evitar conflictos cuando diferentes elementos tienen el mismo nombre, de manera similar a los directorios del sistema operativo que permiten tener diferentes archivos con el mismo nombre siempre que estén almacenados en directorios diferentes. Los espacios de nombres hacen el mismo truco de encapsulación para los elementos de PHP (como clases, rasgos e interfaces) evitando colisiones cuando diferentes elementos tienen el mismo nombre colocándolos en diferentes espacios de nombres.

Los espacios de nombres son imprescindibles cuando interactuamos con bibliotecas de terceros, ya que no podemos controlar cómo se nombrarán sus elementos, lo que genera posibles colisiones al usar nombres estándar como "Archivo", "Registrador" o "Cargador" para nuestros elementos. Además, incluso dentro de un solo proyecto, los espacios de nombres evitan que los nombres de las clases se vuelvan extremadamente largos para evitar conflictos con otras clases, lo que podría resultar en nombres como "MyProject_Controller_FileUpload".

Los espacios de nombres se definen usando la palabra clave namespace (ubicada en la línea inmediatamente después de abrir <?php ) y pueden abarcar varios niveles o subespacios de nombres (similar a tener varios subdirectorios donde se coloca un archivo), que se separan usando \ :

 <?php namespace CoolSoft\ImageResizer\Controllers; class ImageUpload { }

Para acceder a la clase anterior, debemos calificar completamente su nombre, incluido su espacio de nombres (y comenzando con \ ):

 $imageUpload = new \CoolSoft\ImageResizer\Controllers\ImageUpload();

O también podemos importar la clase al contexto actual, después de lo cual podemos hacer referencia a la clase por su nombre directamente:

 use CoolSoft\ImageResizer\Controllers\ImageUpload; $imageUpload = new ImageUpload();

Al nombrar los espacios de nombres siguiendo las convenciones establecidas, podemos obtener beneficios adicionales. Por ejemplo, al seguir la recomendación de estándares PHP PSR-4, la aplicación puede usar el mecanismo de carga automática de Composer para cargar archivos, lo que reduce la complejidad y agrega interoperabilidad sin fricción entre las dependencias. Esta convención establece incluir el nombre del proveedor (por ejemplo, el nombre de la empresa) como el subespacio de nombres superior, seguido opcionalmente por el nombre del paquete, y solo luego seguido de una estructura interna en la que cada subespacio de nombres corresponde a un directorio con el mismo nombre. El resultado asigna 1 a 1 la ubicación física del archivo en la unidad con el espacio de nombres del elemento definido en el archivo.

Rasgos

Los rasgos se agregaron a PHP 5.4, por lo que actualmente faltan por completo en el núcleo de WordPress.

PHP admite la herencia única, por lo que una subclase se deriva de una sola clase principal y no de varias. Por lo tanto, las clases que no se extienden entre sí no pueden reutilizar el código a través de la herencia de clases. Traits es un mecanismo que permite la composición horizontal del comportamiento, lo que hace posible reutilizar código entre clases que viven en diferentes jerarquías de clases.

Un rasgo es similar a una clase, sin embargo, no se puede instanciar por sí solo. En cambio, se puede pensar que el código definido dentro de un rasgo se "copia y pega" en la clase de composición en el momento de la compilación.

Un rasgo se define usando la palabra clave de trait , después de lo cual se puede importar a cualquier clase a través de la palabra clave de use . En el siguiente ejemplo, dos clases Person y Shop que no están relacionadas pueden reutilizar el mismo código a través de un rasgo Addressable :

 trait Addressable { protected $address; public function getAddress() { return $this->address; } public function setAddress($address) { $this->address = $address; } } class Person { use Addressable; } class Shop { use Addressable; } $person = new Person('Juan Carlos'); $person->setAddress('Obelisco, Buenos Aires');

Una clase también puede componer más de un rasgo:

 trait Exportable { public class exportToCSV($filename) { // Iterate all properties and export them to a CSV file } } class Person { use Addressable, Exportable; }

Los rasgos también pueden estar compuestos por otros rasgos, definir métodos abstractos y ofrecer un mecanismo de resolución de conflictos cuando dos o más rasgos compuestos tienen el mismo nombre de función, entre otras características.

Interfaces

Se agregaron interfaces a PHP 5, por lo que WordPress ya hace uso de esta función, sin embargo, con mucha moderación: ¡el núcleo incluye menos de diez interfaces en total!

Las interfaces permiten crear código que especifica qué métodos deben implementarse, pero sin tener que definir cómo se implementan realmente estos métodos. Son útiles para definir contratos entre componentes, lo que conduce a una mejor modularidad y mantenibilidad de la aplicación: una clase que implementa una interfaz puede ser una caja negra de código, y mientras las firmas de las funciones en la interfaz no cambien, la el código se puede actualizar a voluntad sin producir cambios importantes, lo que puede ayudar a prevenir la acumulación de deuda técnica. Además, pueden ayudar a reducir el bloqueo de proveedores, al permitir cambiar la implementación de alguna interfaz a la de un proveedor diferente. Como consecuencia, es imperativo codificar la aplicación contra interfaces en lugar de implementaciones (y definir cuáles son las implementaciones reales a través de la inyección de dependencia).

Las interfaces se definen usando la palabra clave de interface , y deben enumerar solo la firma de sus métodos (es decir, sin tener sus contenidos definidos), que deben tener visibilidad public (por defecto, agregar la palabra clave sin visibilidad también lo hace público):

 interface FileStorage { function save($filename, $contents); function readContents($filename); }

Una clase define que implementa la interfaz a través de la palabra clave implements :

 class LocalDriveFileStorage implements FileStorage { function save($filename, $contents) { // Implement logic } function readContents($filename) { // Implement logic } }

Una clase puede implementar más de una interfaz, separándolas con , :

 interface AWSService { function getRegion(); } class S3FileStorage implements FileStorage, AWSService { function save($filename, $contents) { // Implement logic } function readContents($filename) { // Implement logic } function getRegion() { return 'us-east-1'; } }

Dado que una interfaz declara la intención de lo que se supone que debe hacer un componente, es extremadamente importante nombrar las interfaces de manera adecuada.

Cierres

Los cierres se agregaron a PHP 5.3, por lo que actualmente faltan por completo en el núcleo de WordPress.

Los cierres son un mecanismo para implementar funciones anónimas, lo que ayuda a despejar el espacio de nombres global de las funciones de un solo uso (o que se usan con poca frecuencia). Técnicamente hablando, los cierres son instancias de la clase Closure ; sin embargo, en la práctica, lo más probable es que podamos ignorar felizmente este hecho sin ningún daño.

Antes de los cierres, cada vez que pasaba una función como argumento a otra función, teníamos que definir la función de antemano y pasar su nombre como argumento:

 function duplicate($price) { return $price*2; } $touristPrices = array_map('duplicate', $localPrices);

Con los cierres, una función anónima (es decir, sin nombre) ya se puede pasar directamente como parámetro:

 $touristPrices = array_map(function($price) { return $price*2; }, $localPrices);

Los cierres pueden importar variables a su contexto a través de la palabra clave use :

 $factor = 2; $touristPrices = array_map(function($price) use($factor) { return $price*$factor; }, $localPrices);

Generadores

Se agregaron generadores a PHP 5.5, por lo que actualmente no se encuentran en el núcleo de WordPress.

Los generadores proporcionan una manera fácil de implementar iteradores simples. Un generador permite escribir código que usa foreach para iterar sobre un conjunto de datos sin necesidad de construir una matriz en la memoria. Una función generadora es lo mismo que una función normal, excepto que en lugar de regresar una vez, puede yield tantas veces como sea necesario para proporcionar los valores que se van a iterar.

 function xrange($start, $limit, $step = 1) { for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } foreach (xrange(1, 9, 2) as $number) { echo "$number "; } // This prints: 1 3 5 7 9

Declaraciones de tipo de argumento y devolución

Se introdujeron diferentes declaraciones de tipos de argumentos en diferentes versiones de PHP: WordPress ya puede declarar interfaces y matrices (que no lo hace: apenas encontré una instancia de una función que declara una matriz como parámetro en el núcleo, y no hay interfaces), y lo hará pronto podrá declarar callables (agregado en PHP 5.4) y tipos escalares: bool, float, int y string (agregado en PHP 7.0). Se agregaron declaraciones de tipo de devolución a PHP 7.0.

Las declaraciones de tipo de argumento permiten que las funciones declaren de qué tipo específico debe ser un argumento. La validación se ejecuta en el momento de la llamada, lanzando una excepción si el tipo de argumento no es el declarado. Las declaraciones de tipo de retorno son el mismo concepto, sin embargo, especifican el tipo de valor que será devuelto por la función. Las declaraciones de tipo son útiles para que la intención de la función sea más fácil de entender y para evitar errores de tiempo de ejecución al recibir o devolver un tipo inesperado.

El tipo de argumento se declara antes del nombre de la variable del argumento y el tipo de retorno se declara después de los argumentos, precedido por : :

 function foo(boolean $bar): int { }

Las declaraciones de tipo de argumento escalar tienen dos opciones: coercitiva y estricta. En el modo coercitivo, si se pasa el tipo incorrecto como parámetro, se convertirá al tipo correcto. Por ejemplo, una función a la que se le asigna un número entero para un parámetro que espera una cadena obtendrá una variable de tipo cadena. En modo estricto, solo se aceptará una variable del tipo exacto de declaración.

El modo coercitivo es el predeterminado. Para habilitar el modo estricto, debemos agregar una declare de declaración utilizada con la declaración de strict_types :

 declare(strict_types=1); function foo(boolean $bar) { }

Nueva sintaxis y operadores

WordPress ya puede identificar listas de argumentos de longitud variable a través de la función func_num_args . A partir de PHP 5.6, podemos usar el token ... para indicar que la función acepta un número variable de argumentos, y estos argumentos se pasarán a la variable dada como una matriz:

 function sum(...$numbers) { $sum = 0; foreach ($numbers as $number) { $sum += $number; } return $sum; }

A partir de PHP 5.6, las constantes pueden involucrar expresiones escalares que involucran literales numéricos y de cadena en lugar de solo valores estáticos, y también matrices:

 const SUM = 37 + 2; // A scalar expression const LETTERS = ['a', 'b', 'c']; // An array

A partir de PHP 7.0, las matrices también se pueden definir usando define :

 define('LETTERS', ['a', 'b', 'c']);

PHP 7.0 agregó un par de nuevos operadores: el operador Nulo coalescente ( ?? ) y el operador Nave espacial ( <=> ).

El operador coalescente nulo ?? es azúcar sintáctico para el caso común de necesitar usar un ternario junto con isset(). Devuelve su primer operando si existe y no es NULL; de lo contrario, devuelve su segundo operando.

 $username = $_GET['user'] ?? 'nobody'; // This is equivalent to: // $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

El operador Spaceship <=> se utiliza para comparar dos expresiones, devolviendo -1, 0 o 1 cuando el primer operando es respectivamente menor, igual o mayor que el segundo operando.

 echo 1 <=> 2; // returns -1 echo 1 <=> 1; // returns 0 echo 2 <=> 1; // returns 1

Estas son las nuevas características más importantes agregadas a PHP que abarcan las versiones 5.3 a 7.0. La lista de las nuevas funciones adicionales, que no aparecen en este artículo, se puede obtener consultando la documentación de PHP sobre cómo migrar de una versión a otra.

A continuación, analizamos cómo podemos aprovechar al máximo todas estas nuevas funciones y las tendencias recientes en el desarrollo web para producir un mejor software.

Recomendaciones de estándares PHP

Las recomendaciones de estándares de PHP fueron creadas por un grupo de desarrolladores de PHP de marcos y bibliotecas populares, que intentan establecer convenciones para que los diferentes proyectos puedan integrarse de manera más fluida y los diferentes equipos puedan trabajar mejor entre sí. Las recomendaciones no son estáticas: las recomendaciones existentes pueden quedar obsoletas y crear otras más nuevas para reemplazarlas, y otras nuevas se publican de forma continua.

Las recomendaciones actuales son las siguientes:

Grupo Recomendación Descripción
Estilos de codificación
El formato estandarizado reduce la fricción cognitiva al leer código de otros autores
PSR-1 Estándar de codificación básica
PSR-2 Guía de estilo de codificación
Carga automática
Los cargadores automáticos eliminan la complejidad de incluir archivos al asignar espacios de nombres a las rutas del sistema de archivos
PSR-4 Carga automática mejorada
Interfaces
Las interfaces simplifican el intercambio de código entre proyectos siguiendo los contratos esperados
PSR-3 Interfaz de registrador
PSR-6 Interfaz de almacenamiento en caché
PSR-11 Interfaz de contenedor
PSR-13 Enlaces hipermedia
PSR-16 caché simple
HTTP
Estándares e interfaces interoperables para tener un enfoque agnóstico para manejar solicitudes y respuestas HTTP, tanto en el lado del cliente como en el del servidor
PSR-7 Interfaces de mensajes HTTP
PSR-15 Controladores HTTP
PSR-17 HTTP Fábricas
PSR-18 Cliente HTTP

Piense y codifique en componentes

Los componentes hacen posible utilizar las mejores características de un marco sin estar encerrado en el propio marco. Por ejemplo, Symfony se ha lanzado como un conjunto de componentes PHP reutilizables que se pueden instalar independientemente del marco Symfony; Laravel, otro marco PHP, hace uso de varios componentes de Symfony y lanzó su propio conjunto de componentes reutilizables que pueden ser utilizados por cualquier proyecto de PHP.

Todos estos componentes se publican en Packagist, un repositorio de paquetes PHP públicos, y se pueden agregar fácilmente a cualquier proyecto PHP a través de Composer, un administrador de dependencias extremadamente popular para PHP.

WordPress debería ser parte de un ciclo de desarrollo tan virtuoso. Desafortunadamente, el núcleo de WordPress en sí no está construido con componentes (como lo demuestra la ausencia casi total de interfaces) y, además, ni siquiera tiene el archivo composer.json necesario para habilitar la instalación de WordPress a través de Composer. Esto se debe a que la comunidad de WordPress no ha acordado si WordPress es una dependencia de un sitio (en cuyo caso se justificaría instalarlo a través de Composer) o si es el sitio en sí (en cuyo caso, Composer puede no ser la herramienta adecuada para el trabajo) .

En mi opinión, si esperamos que WordPress siga siendo relevante durante los próximos quince años (al menos WordPress como CMS backend), entonces WordPress debe reconocerse como una dependencia del sitio y estar disponible para su instalación a través de Composer . La razón es muy simple: con apenas un comando en la terminal, Composer permite declarar e instalar las dependencias de un proyecto de los miles de paquetes publicados en Packagist, lo que hace posible crear aplicaciones PHP extremadamente poderosas en muy poco tiempo, y a los desarrolladores les encanta. trabajando de esta manera. Si WordPress no se adapta a este modelo, puede perder el apoyo de la comunidad de desarrollo y caer en el olvido, tanto como FTP cayó en desgracia después de la introducción de las implementaciones basadas en Git.

Yo diría que el lanzamiento de Gutenberg ya demuestra que WordPress es una dependencia del sitio y no el sitio en sí mismo: Gutenberg trata a WordPress como un CMS sin cabeza y también puede operar con otros sistemas de back-end, como lo ejemplifica Drupal Gutenberg. Por lo tanto, Gutenberg deja en claro que el CMS que alimenta un sitio puede intercambiarse, por lo que debe tratarse como una dependencia. Además, se pretende que Gutenberg se base en componentes de JavaScript publicados a través de npm (como lo explicó el responsable central Adam Silverstein), por lo que si se espera que el cliente de WordPress administre sus paquetes de JavaScript a través del administrador de paquetes de npm, ¿por qué no extender esta lógica a el backend para administrar las dependencias de PHP a través de Composer?

Ahora las buenas noticias: no es necesario esperar a que se resuelva este problema, ya que es posible tratar WordPress como una dependencia del sitio e instalarlo a través de Composer. John P. Bloch ha duplicado el núcleo de WordPress en Git, agregó un archivo composer.json y lo lanzó en Packagist, y Bedrock de Roots proporciona un paquete para instalar WordPress con una estructura de carpetas personalizada con soporte para herramientas de desarrollo modernas y seguridad mejorada. Y los temas y complementos también están cubiertos; Siempre que se hayan incluido en los directorios de complementos y temas de WordPress, están disponibles en WordPress Packagist.

Como consecuencia, es una opción sensata crear código de WordPress sin pensar en términos de temas y complementos, sino pensando en términos de componentes, haciéndolos disponibles a través de Packagist para ser utilizados por cualquier proyecto PHP, y además empaquetados y lanzados como temas y complementos para el uso específico de WordPress. Si el componente necesita interactuar con las API de WordPress, estas API se pueden abstraer detrás de una interfaz que, si surge la necesidad, también se puede implementar para otros CMS.

Adición de un motor de plantilla para mejorar la capa de vista

Si seguimos la recomendación de pensar y codificar en componentes, y tratamos a WordPress como una dependencia del sitio distinta del sitio en sí, entonces nuestros proyectos pueden liberarse de los límites impuestos por WordPress e importar ideas y herramientas tomadas de otros marcos.

La representación de contenido HTML en el lado del servidor es un buen ejemplo, que se realiza a través de plantillas PHP simples. Esta capa de vista se puede mejorar a través de los motores de plantillas Twig (de Symfony) y Blade (de Laravel), que proporcionan una sintaxis muy concisa y funciones potentes que le otorgan una ventaja sobre las plantillas simples de PHP. En particular, los bloques dinámicos de Gutenberg pueden beneficiarse fácilmente de estos motores de plantillas, ya que su proceso para representar el HTML del bloque en el lado del servidor está desacoplado de la arquitectura de jerarquía de plantillas de WordPress.

Arquitecto La Aplicación Para El Uso General

Codificar contra interfaces y pensar en términos de componentes nos permite diseñar una aplicación para uso general y personalizarla para el uso específico que necesitamos ofrecer, en lugar de codificar solo para el uso específico de cada proyecto que tenemos. Aunque este enfoque es más costoso a corto plazo (implica trabajo adicional), vale la pena a largo plazo cuando se pueden entregar proyectos adicionales con menos esfuerzo simplemente personalizando una aplicación de uso general.

Para que este enfoque sea efectivo, se deben tener en cuenta las siguientes consideraciones:

Evite las dependencias fijas (tanto como sea posible)

jQuery y Bootstrap (o Foundation, o <–inserte su biblioteca favorita aquí–> ) podrían haber sido considerados imprescindibles hace algunos años, sin embargo, han ido perdiendo terreno constantemente frente a Vanilla JS y las nuevas características nativas de CSS. Por lo tanto, un proyecto de uso general codificado hace cinco años que dependía de estas bibliotecas puede que ya no sea adecuado hoy en día. Por lo tanto, como regla general, cuanto menor sea la cantidad de dependencias fijas en bibliotecas de terceros, más actualizada resultará a largo plazo.

Mejora progresiva de las funcionalidades

WordPress es un sistema CMS completo que incluye administración de usuarios, por lo tanto, el soporte para la administración de usuarios está incluido de fábrica. Sin embargo, no todos los sitios de WordPress requieren administración de usuarios. Por lo tanto, nuestra aplicación debería tener esto en cuenta y funcionar de manera óptima en cada escenario: admitir la gestión de usuarios cuando sea necesario, pero no cargar los activos correspondientes cuando no lo sea. Este enfoque también puede funcionar gradualmente: supongamos que un cliente necesita implementar un formulario de contacto pero no tiene presupuesto, por lo que lo codificamos usando un complemento gratuito con funciones limitadas, y otro cliente tiene el presupuesto para comprar la licencia de una oferta de complemento comercial. mejores características. Luego, podemos codificar nuestra funcionalidad de forma predeterminada a una funcionalidad muy básica, y usar cada vez más las funciones del complemento con mayor capacidad disponible en el sistema.

Revisión continua de código y documentación

Al revisar periódicamente nuestro código escrito previamente y su documentación, podemos validar si está actualizado con respecto a las nuevas convenciones y tecnologías y, si no lo está, tomar medidas para actualizarlo antes de que la deuda técnica sea demasiado costosa para superar. y tenemos que codificarlo todo de nuevo desde cero.

Lectura recomendada : Esté atento: funciones de PHP y WordPress que pueden hacer que su sitio sea inseguro

Intente minimizar los problemas, pero esté preparado cuando sucedan

Ningún software es 100% perfecto: los errores siempre están ahí, solo que aún no los hemos encontrado. Como tal, debemos asegurarnos de que, una vez que surjan los problemas, sean fáciles de solucionar.

Hazlo simple

El software complejo no se puede mantener a largo plazo: no solo porque otros miembros del equipo pueden no entenderlo, sino también porque la persona que lo codificó puede no entender su propio código complejo dentro de unos años. Por lo que producir software simple debe ser una prioridad, más aún porque solo un software simple puede ser correcto y rápido.

Fallar en tiempo de compilación es mejor que en tiempo de ejecución

Si un fragmento de código se puede validar contra errores en tiempo de compilación o en tiempo de ejecución, entonces debemos priorizar la solución en tiempo de compilación, de modo que el error pueda surgir y tratarse en la etapa de desarrollo y antes de que la aplicación llegue a producción. Por ejemplo, tanto const como define se usan para definir constantes, sin embargo, mientras que const se valida en tiempo de compilación, define se valida en tiempo de ejecución. Entonces, siempre que sea posible, es preferible usar const en lugar de define .

Siguiendo esta recomendación, las funciones de enlace de WordPress contenidas en las clases se pueden mejorar pasando la clase real como un parámetro en lugar de una cadena con el nombre de la clase. En el siguiente ejemplo, si se cambia el nombre de la clase Foo , mientras que el segundo enlace producirá un error de compilación, el primer enlace fallará en el tiempo de ejecución, por lo tanto, el segundo enlace es mejor:

 class Foo { public static function bar() { } } add_action('init', ['Foo', 'bar']); // Not so good add_action('init', [Foo::class, 'bar']); // Much better

Por la misma razón que la anterior, debemos evitar el uso de variables globales (como global $wpdb ): estas no solo contaminan el contexto global y no son fáciles de rastrear de dónde se originan, sino que también, si se les cambia el nombre, el error aparecerá. ser producido en tiempo de ejecución. Como solución, podemos usar un contenedor de inyección de dependencia para obtener una instancia del objeto requerido.

Manejo de errores/excepciones

Podemos crear una arquitectura de objetos de Exception , para que la aplicación pueda reaccionar adecuadamente de acuerdo con cada problema en particular, para recuperarse siempre que sea posible o mostrar un mensaje de error útil al usuario cuando no, y en general para registrar el error para el administrador para solucionar el problema. Y siempre proteja a sus usuarios de la pantalla blanca de la muerte: todos los Error y Exception no detectados se pueden interceptar a través de la función set_exception_handler para imprimir un mensaje de error no aterrador en la pantalla.

Adoptar herramientas de compilación

Las herramientas de compilación pueden ahorrar mucho tiempo al automatizar tareas que son muy tediosas de ejecutar manualmente. WordPress no ofrece integración con ninguna herramienta de compilación específica, por lo que la tarea de incorporarlas al proyecto recaerá completamente en el desarrollador.

Hay diferentes herramientas para lograr diferentes propósitos. Por ejemplo, existen herramientas de compilación para ejecutar tareas para comprimir y cambiar el tamaño de imágenes, minimizar archivos JS y CSS y copiar archivos a un directorio para producir un lanzamiento, como Webpack, Grunt y Gulp; otras herramientas ayudan a crear el andamiaje de un proyecto, lo cual es útil para producir la estructura de carpetas para nuestros temas o complementos, como Yeoman. De hecho, con tantas herramientas disponibles, navegar por los artículos que comparan las diferentes herramientas disponibles ayudará a encontrar la más adecuada para nuestras necesidades.

En algunos casos, sin embargo, no hay herramientas de compilación que puedan lograr exactamente lo que necesita nuestro proyecto, por lo que es posible que debamos codificar nuestra propia herramienta de compilación como una extensión del proyecto en sí. Por ejemplo, hice esto para generar el archivo service-worker.js para agregar soporte para Service Workers en WordPress.

Conclusión

Debido a su fuerte énfasis en mantener la compatibilidad con versiones anteriores, extendida incluso hasta PHP 5.2.4, WordPress no ha podido beneficiarse de las últimas funciones añadidas a PHP, y este hecho ha hecho que WordPress se convierta en una plataforma poco emocionante para codificar. para entre muchos desarrolladores.

Afortunadamente, estos días sombríos pueden terminar pronto, y WordPress puede convertirse en una plataforma brillante y emocionante para codificar una vez más: el requisito de PHP 7.0+ a partir de diciembre de 2019 hará que muchas características de PHP estén disponibles, lo que permitirá a los desarrolladores producir más potentes y software de mayor rendimiento. En este artículo, revisamos las funciones PHP más importantes recientemente disponibles y cómo aprovecharlas al máximo.

El reciente lanzamiento de Gutenberg podría ser una señal de los buenos tiempos que se avecinan: incluso si Gutenberg en sí mismo no ha sido completamente aceptado por la comunidad, al menos demuestra la voluntad de incorporar las últimas tecnologías (como React y Webpack) en el núcleo. . Este giro de los acontecimientos hace que me pregunte: si la interfaz puede cambiar de imagen, ¿por qué no extenderla al backend? Una vez que WordPress requiera al menos PHP 7.0, la actualización a herramientas y metodologías modernas puede acelerarse: tanto como npm se convirtió en el administrador de paquetes de JavaScript elegido, ¿por qué no hacer que Composer se convierta en el administrador oficial de dependencias de PHP? Si los bloques son la nueva unidad para construir sitios en el frontend, ¿por qué no usar componentes PHP como la unidad para incorporar funcionalidades en el backend? Y finalmente, si Gutenberg trata a WordPress como un CMS de back-end intercambiable, ¿por qué no reconocer que WordPress es una dependencia del sitio y no el sitio en sí? Dejaré estas preguntas abiertas para que reflexionen y reflexionen.