Ejemplo hipotético pero aplicabilidad en el mundo real (para alguien que está aprendiendo, como yo).
Dado este código:
<?php
function send_money_to_grandma() {
internetofThings("send grandma","$1");
}
add_action('init','send_money_to_grandma');
add_action('init','send_money_to_grandma');
ok, ahora abro mi sitio WP e inicio sesión. Recorro algunas páginas en Admin. La acción 'init' dispara un total de 100 veces antes de que se agote la batería de mi computadora portátil.
Primeras preguntas ¿Cuánto dinero le enviamos a la abuela? ¿Son $ 1, $ 2, $ 100 o $ 200 (o algo más?)
Si también pudieras explicar tu respuesta, sería increíble.
Segunda pregunta: si queremos asegurarnos de que solo le enviemos $ 1 a la abuela, ¿cuál es la mejor manera de hacerlo? ¿Variable global (semáforo) que se establece como 'verdadera' la primera vez que enviamos $ 1? ¿O hay alguna otra prueba para ver si ya ocurrió una acción y evitar que se dispare varias veces?
Tercera pregunta: ¿Es esto algo de lo que se preocupan los desarrolladores de complementos? Me doy cuenta de que mi ejemplo es tonto, pero estaba pensando en problemas de rendimiento y otros efectos secundarios inesperados (por ejemplo, si la función se actualiza / inserta en la base de datos).
Respuestas:
Aquí hay algunos pensamientos al azar sobre esto:
Pregunta 1
Para 100 cargas de página, le enviamos 100 x $ 1 = $ 100.
Aquí en realidad queremos decir
100 x do_action( 'init' )
llamadas.No importaba que lo añadiéramos dos veces con:
porque las devoluciones de llamada y las prioridades (por defecto 10) son idénticas .
Podemos verificar cómo
add_action
es solo un contenedor paraadd_filter
que construya la$wp_filter
matriz global :Sin embargo, si cambiamos la prioridad:
entonces le enviaríamos 2 x $ 1 por carga de página o $ 200 por 100 cargas de página.
Lo mismo si las devoluciones de llamada son diferentes:
Pregunta 2
Si solo queremos enviarlo una vez por carga de página , esto debería hacerlo:
porque el
init
gancho solo se dispara una vez. Es posible que tengamos otros ganchos que se activan muchas veces por carga de página.Llamemos:
pero que pasa si
someaction
dispara 10 veces por carga de página?Podríamos ajustar la
send_money_to_grandma()
función cono use una variable estática como contador:
Si solo queremos ejecutarlo una vez (¡alguna vez!), Entonces podríamos registrar una opción en la
wp_options
tabla a través de la API de Opciones :Si queremos enviarle dinero una vez al día, entonces podemos usar la API transitoria
o incluso usar el wp-cron.
Tenga en cuenta que puede tener llamadas ajax. también.
Hay formas de verificarlos, por ejemplo, con
DOING_AJAX
También puede haber redirecciones, que podrían interrumpir el flujo.
Entonces podríamos querer restringir solo al backend,
is_admin()
o no:! is_admin()
.Pregunta 3
Sí, esto es importante.
Si queremos hacer muy feliz a nuestra abuela, haríamos:
pero esto sería muy malo para el rendimiento ... y nuestra billetera ;-)
fuente
Esto es más un comentario a la muy buena respuesta de Birgire que una respuesta completa, pero al tener que escribir el código, los comentarios no encajan.
De la respuesta puede parecer que la única razón por la que se agrega acción una vez en el código de muestra OP, incluso si
add_action()
se llama dos veces, es el hecho de que se utiliza la misma prioridad. Eso no es cierto.En el código de
add_filter
una parte importante está la_wp_filter_build_unique_id()
función call, que crea una identificación única por devolución de llamada .Si usa una variable simple, como una cadena que contiene un nombre de función, por ejemplo
"send_money_to_grandma"
, la identificación será igual a la cadena en sí, por lo que si la prioridad es la misma, siendo la misma también, la devolución de llamada se agrega una vez.Sin embargo, las cosas no siempre son así de simples. Las devoluciones de llamada pueden ser cualquier cosa que esté
callable
en PHP:Los dos primeros están representados, respectivamente, por una cadena y una matriz de 2 cadenas (
'send_money_to_grandma'
yarray('MoneySender', 'send_to_grandma')
) por lo que la identificación es siempre la misma, y puede estar seguro de que la devolución de llamada se agrega una vez si la prioridad es la misma.En los otros 3 casos, la identificación depende de las instancias del objeto (una función anónima es un objeto en PHP), por lo que la devolución de llamada se agrega una vez solo si el objeto es la misma instancia , y es importante tener en cuenta esa misma instancia y la misma clase Son dos cosas diferentes.
Toma este ejemplo:
¿Cuántos dólares enviamos por carga de página?
La respuesta es 2, porque la identificación que WordPress genera
$sender1
y$sender2
es diferente.Lo mismo sucede en este caso:
Arriba utilicé la función
sent_to_grandma
dentro de los cierres, e incluso si el código es idéntico, los 2 cierres son 2 instancias diferentes de\Closure
objeto, por lo que WP creará 2 identificadores diferentes, lo que hará que la acción se agregue dos veces, incluso si la prioridad es la misma.fuente
No puedes agregar el misma acción al mismo enlace de acción , con la misma prioridad .
Esto se hace para evitar que varios complementos que se basan en la acción de un complemento de terceros sucedan más de una vez (piense en woocommerce y todos sus complementos de terceros, como las integraciones de pago de pasarela, etc.). Entonces, sin especificar la prioridad, la abuela sigue siendo pobre:
Sin embargo, si agrega prioridad a esas acciones:
La abuela ahora muere con $ 4 en su bolsillo (1, 2, 3 y el valor predeterminado: 10).
fuente