Ganchos, línea y hundimiento: nuevo wp_hook una clase A WordPress


El sistema de gancho es un pilar central de WordPress y, con el lanzamiento 4.7, se ha combinado una revisión importante de la forma en que funciona. El boleto tracio que inicialmente planteó un problema con el sistema de gancho se registró hace más de 6 años. Después de algunos intentos, las actualizaciones finalmente llegaron a la versión 4.7 y se revisó el venerable sistema de gancho. En esta publicación, quiero repasar algunos de los cambios técnicos y decisiones que han ingresado a la nueva clase WP_HOOK. También superaré algunos de los aspectos más interesantes del desarrollo básico de WordPress y analizaré lo que se necesita para revisar una característica importante de WordPress.
Para el propósito de esta publicación, asumiré que sabes lo que WordPress gira (es decir, add_filter (), add_action (), apply_filters () y do_action ()) y tienes una idea general de cómo funciona. También sería una buena idea leer la publicación en el blog hacer que cubra los cambios. ¿Que ha cambiado? Uno de los mayores cambios en WordPress 4.7 es que hay una nueva clase WP_HOOK. Esta nueva clase ahora se usa para administrar todos los ganchos internos en el núcleo de WordPress. Es una gran cosa. Antes de 4.7, todas las funciones de gancho (add_filter (), etc.) y la lógica se administraron directamente en WP-Includes/Plugin.php. Ahora, la clase WP_HOOK se incluye desde WP-Includes/Plugin.php y cada característica de filtro esencialmente recurre al método WP_Hook apropiado.
Por ejemplo, este es el clásico add_filter () ahora: function add_filter ($ tag, $ funcional_to_add, $ priority = 10, $ acepta_args = 1) {global $ wp_filter; if (! Isset ($ wp_filter [$ tag])) {$ wp_filter [$ tag] = new WP_Hook (); } $ wp_filter [$ tag]-> add_filter ($ tag, $ functy_to_add, $ priority, $ acepth_args); devolver verdadero; } Como puede ver, la variable global $ wp_filter [$ etiqueta] Ahora asigno una nueva instancia de wp_hoook, que luego llama al wp_hoook :: add_filter () apropiado. Compare esto con la versión anterior: function add_filter ($ tag, $ functy_to_add, $ priority = 10, $ acepta_args = 1) {global $ wp_filter, $ striffilters; $ IDX = _WP_FILTER_BUILD_UNIQUE_ID ($ TAG, $ function_to_add, $ priority); $ wp_filter [$ tag] [$ priority] [$ idx] = array (‘function’ => $ function_to_add, ‘actor_args’ => $ aceptación_args); Unset ($ MAPD_FILTERS [$ TAG]); devolver verdadero; } La parte clave aquí es que las versiones anteriores 4.7 de esta función crean una matriz multidimensional ($ wp_filter) para mantener todos los filtros en la cola. En la nueva versión, parte de esta lógica se trasladó a la clase WP_Hook, pero como podemos ver, $ WP_FILTER ya no es una matriz profundamente vestida, sino una matriz.
Para mantener la compatibilidad inversa y evitar la ruptura del código de las personas, la clase WP_HOOK implementa las interfaces ArrayAccess e Iterator. Simplemente, estas dos interfaces permiten que la clase WP_Hook sea accesible y funcione como una matriz, sin embargo, con toda la funcionalidad de un objeto. El rendimiento fue una gran preocupación para las nuevas funciones de filtro. El antiguo sistema de gancho era extremadamente rápido, la mayoría de los sitios lo golpearon miles de veces a pedido. ¿Era importante mantener el rendimiento, entonces por qué un sistema de gancho actualizado utilizaría una implementación más abstracta, potencialmente lenta basada en objetos? La respuesta está en la forma en que los punteros de la matriz operan con el bucle do-while. Jonathan Brinly va más allá del problema principal con el sistema de gancho (y, en consecuencia, vinieron con una gran parte de la solución). Lo que se resume es que el antiguo add_action () se usó un bucle foreach dentro de un bucle de hacer, con una llamada a Siguiente ($ wp_filter [$ tag]) en la cláusula: do {foreach ((matriz) corriente ($ wp_filter [$ tag]) como $ the_) if (! is_ull ($ the _ [‘function’)) {$ args [1] = $ valor; $ value = call_use_func_array ($ the _ [‘function’], array_slice ($ args, 1, (int) $ the _ [‘acepta_args])); }} While (next ($ wp_filter [$ tag])! == falso); La primera oración en el boleto TRAC enfatiza el problema principal con esta lógica:
Al llamar a un gancho particular desde una función que ha sido llamada por el mismo gancho, las funciones hocgadas restantes de la primera iteración serán eliminadas. El problema surge debido a la apelación, especialmente cuando una llamada inversa se conecta a la misma acción. Jonathan tiene un buen ejemplo a este respecto en su publicación: function my_first_callback ($ post_id, $ post) {if ($ post-> post_type == ‘post’) {wp_insert_post (array (‘post_title’ => un post ‘,’ ” post_status ‘=>’ publicar ‘,’ post_type ‘=> a_custom_post_type’,)); }} function my_second_callback ($ post_id, $ post) {// hacer algo más} add_action (‘save_post’, ‘my_first_callback’, 10, 2); // nunca se llamó add_action (‘save_post’, ‘my_second_callback’, 15, 2); ¿Observe la colocación de la función wp_insert_post ()? La llamada de función activará otra acción save_post, creando un bucle vestido, recursivo de llamadas inversas. Esta llamada vestida wp_insert_post () desencadena do_action (‘save_post’) y hace que la función do_action circule a través de $ wp_filter [‘save_post’]. Esto sucede hasta que se activa una llamada a PHP Next () en la cláusula While. Debido a la imbridación de llamadas Do_Action, en este momento el puntero de matriz se mueve al final de $ wp_filter [‘save_post’] y el bucle se completa. En este escenario, add_action (‘save_post’, ‘my_second_callback’, 15, 2) nunca se llama. Si recuerda cuán estructurado $ wp_filter, verá por qué es:
$ wp_filter [$ tag] [$ priority] [$ idx] = array (‘function’ => $ function_to_add, ‘actor_args’ => $ aceptación_args); En este caso, el interior de $ wp_filter [‘save_post’] se activa hasta que el siguiente () se llama indicador de matriz al final de la matriz interna. Después de que se complete ese bucle, cualquier acción futura conectada al nivel superior de $ WP_Filter con una prioridad posterior no se ejecuta. Esto se debe a que WordPress cree que $ wp_filter fue completamente bucle. do {foreach ((array) actual ($ wp_filter [$ tag]) como $ the_) {if (! is_ull ($ the _ [‘function’)) {$ args [1] = $ valor; $ value = call_use_func_array ($ the _ [‘function’], array_slice ($ args, 1, (int) $ the _ [‘acepta_args])); }}} while (next ($ wp_filter [$ tag])! == falso); // callbacks [$ priority]); $ this-> callbacks [$ priority] [$ idx] = array (‘function’ => $ function_to_add, ‘actor_args’ => $ aceptación_args); // Si estamos agregando una nueva prioridad a la lista, vuelva a poner el orden ordenado (! } If ($ this-> nesting_level> 0) {$ this-> resort_active_iterations ($ priority, $ priority_existered); }} Antiguo add_filter (): function add_filter ($ tag, $ functy_to_add, $ priority = 10, $ acepth_args = 1) {global $ wp_filter, $ mrifffilters; $ IDX = _WP_FILTER_BUILD_UNIQUE_ID ($ TAG, $ function_to_add, $ priority); $ wp_filter [$ tag] [$ priority] [$ idx] = array (‘function’ => $ function_to_add, ‘actor_args’ => $ aceptación_args); Unset ($ MAPD_FILTERS [$ TAG]); devolver verdadero; } ¿Notan que la nueva llamada a $ this-> resort_active_iterations ($ priority, $ priority_existered) en el nuevo código? Este es un nuevo método que se ha creado para administrar el reinicio de las prioridades de llamadas inversas durante una iteración. Este método es parte de qué remedios el problema de la prioridad de la iteración mencionada anteriormente. ¿Todos estos bucles hacen que tu cabeza se dé vuelta?
Al ejecutar cada filtro, puede ver las diferencias. El nuevo código APLICE_FILTERS () en WP_HOOK: función pública APLICE_FILTERS ($ valor, $ args) {if (! $ This-> llamadas) {return $ value; } $ Nesting_level = $ this-> nesting_level ++; $ this-> iterations [$ nesting_level] = array_keys ($ this-> callbacks); $ num_args = count ($ args); do {$ this-> current_priority [$ nesting_level] = $ priority = current ($ this-> iterates [$ nesting_level]); Foreach ($ this-> callbacks [$ priority] como $ the_) {if (! $ This-> doing_action) {$ args [0] = $ valor; } // Evite el array_slici si es posible. if ($ the _ [‘ácert_args’] == 0) {$ value = call_user_func_array ($ the _ [‘function’, array ()); } Elseif ($ the _ [‘Acept_args’]> = $ num_args) {$ valor = call_user_func_array ($ the _ [‘function’, $ args); } else {$ value = call_user_func_array ($ the _ [‘function’], array_slice ($ args, 0, (int) $ the _ [‘acepta_args]); }}} while (false! == Next ($ this-> iterations [$ nesting_level]); Unset ($ this-> iterations [$ nesting_level]); Unset ($ this-> current_priority [$ nesting_level]); $ this-> nesting_level–; Devolver $ valor; } El código antiguo APLICE_FILTERS () de WP-Includes/Plugin.Php: Function APLICE_FILTERS ($ TAG, $ valor) {global $ wp_filter, $ mriffilters, $ wp_current_filter; … do {foreach ((array) actual ($ wp_filter [$ tag]) como $ the_) if (! is_ull ($ the _ [‘function’)) {$ args [1] = $ valor; $ value = call_use_func_array ($ the _ [‘function’], array_slice ($ args, 1, (int) $ the _ [‘acepta_args])); }} While (next ($ wp_filter [$ tag])! == falso); array_pop ($ wp_current_filter); Devolver $ valor;

} Como puede ver, la nueva versión del código administra la iteración del filtro actual, así como la condición del filtro actual al aplicar la llamada inversa. La versión anterior de Apply_Filters () no ha tenido en cuenta el nivel de vergüenza, iteración o prioridad del gancho que se ejecuta actualmente. La compatibilidad inversa, como probablemente sepa, uno de los conceptos clave en el desarrollo básico de WordPress es la compatibilidad inversa. WordPress hace un gran trabajo para asegurarse de que el código anterior en complementos y temas todavía se ejecute con la última versión. A menudo, esto significa que las funciones de PHP más recientes no se pueden usar y requiere el pensamiento creativo para mantener las cosas que funcionen con el código heredado. En el caso de WP_HOOK, esto significaba el uso de interfaces de ArrayAccess e iterador para mantener la funcionalidad de la “matriz similar” para el código anterior que alcanzó directamente $ wp_filter. Analizando el historial del parche, gran parte del código inicial para la clase WP_HOOK ha pasado por un reflector considerable para admitir PHP 5.2. Ya sea que esté de acuerdo o no, está claro que los desarrolladores básicos de WordPress tienen en cuenta la compatibilidad inversa y aseguran que todo el código nuevo (especialmente el código que afecta a cada desarrollador) funcione, independientemente del entorno. ¿Qué significa esto para los desarrolladores?

Copyright statement: Unless otherwise noted, this article is Collected from the Internet, please keep the source of the article when reprinting.

Check Also

gkOVSBm5B8SgiXmo

Shopify vs WooCommerce – ¿Cuál es la mejor plataforma?(Comparación)

Shopify vs WooCommerce

Leave a Reply

Your email address will not be published. Required fields are marked *