Exemplo hipotético, mas aplicabilidade no mundo real (para alguém que está aprendendo, como eu).
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, agora eu trago o meu site WP e entro. Atravesso algumas páginas no Admin. A ação 'init' dispara um total de 100 vezes antes que a bateria do meu laptop acabe.
Primeiras perguntas: quanto dinheiro enviamos para a avó? É $ 1, $ 2, $ 100 ou $ 200 (ou algo mais?)
Se você também pudesse explicar sua resposta, isso seria incrível.
Segunda pergunta: se queremos ter certeza de enviar apenas US $ 1 para a avó, qual é a melhor maneira de fazer isso? Variável global (semáforo) que é definida como 'true' na primeira vez que enviamos $ 1? Ou existe algum outro teste para ver se uma ação já aconteceu e impedir que ela seja disparada várias vezes?
Terceira pergunta: Isso é algo com que os desenvolvedores de plugins se preocupam? Percebo que meu exemplo é bobo, mas eu estava pensando em problemas de desempenho e outros efeitos colaterais inesperados (por exemplo, se a função for atualizada / inserida no banco de dados).
Respostas:
Aqui estão alguns pensamentos aleatórios sobre isso:
Questão 1
Para 100 carregamentos de página, enviamos 100 x $ 1 = $ 100.
Aqui, na verdade, queremos dizer
100 x do_action( 'init' )
chamadas.Não importava que o adicionássemos duas vezes com:
porque os retornos de chamada e as prioridades (padrão 10) são idênticos .
Podemos verificar como o
add_action
é apenas um invólucroadd_filter
que constrói a$wp_filter
matriz global :Se, no entanto, alterássemos a prioridade:
enviaríamos a ela 2 x US $ 1 por carregamento de página ou US $ 200 por 100 carregamentos de página.
O mesmo se os retornos de chamada forem diferentes:
Questão 2
Se quisermos enviá-lo apenas uma vez por carregamento de página , faça o seguinte:
porque o
init
gancho é acionado apenas uma vez. Podemos ter outros ganchos que são acionados muitas vezes por carregamento de página.Vamos ligar:
mas o que acontece se
someaction
disparar 10 vezes por carregamento de página?Nós poderíamos ajustar a
send_money_to_grandma()
função comou use uma variável estática como um contador:
Se quisermos executá-lo apenas uma vez (sempre!), Poderemos registrar uma opção na
wp_options
tabela através da API de opções :Se quisermos enviar dinheiro a ela uma vez por dia, podemos usar a API transitória
ou até mesmo usar o wp-cron.
Observe que você pode ter chamadas ajax. também.
Existem maneiras de verificar isso, por exemplo, com
DOING_AJAX
Também pode haver redirecionamentos, que podem interromper o fluxo.
Então nós pode querer restringir somente, para o servidor
is_admin()
ou não:! is_admin()
.Questão 3
sim, isso é importante.
Se queremos deixar nossa avó muito feliz, faremos:
mas isso seria muito ruim para o desempenho ... e nossa carteira ;-)
fonte
Isso é mais um comentário para a resposta muito boa de Birgire do que uma resposta completa, mas, tendo que escrever código, os comentários não se encaixam.
A partir da resposta, pode parecer que a única razão pela qual a ação é adicionada uma vez no código de amostra OP, mesmo que
add_action()
seja chamada duas vezes, é o fato de a mesma prioridade ser usada. Isso não é verdade.No código de
add_filter
uma parte importante está a_wp_filter_build_unique_id()
chamada de função, que cria um ID exclusivo por retorno de chamada .Se você usar uma variável simples, como uma string que contém um nome de função, por exemplo
"send_money_to_grandma"
, o id será igual à string em si, portanto, se a prioridade for a mesma, sendo a id a mesma, o retorno de chamada será adicionado uma vez.No entanto, as coisas nem sempre são simples assim. Os retornos de chamada podem ser qualquer coisa que esteja
callable
no PHP:As duas primeiras são representadas, respectivamente, por uma sequência e uma matriz de 2 sequências (
'send_money_to_grandma'
earray('MoneySender', 'send_to_grandma')
), para que o ID seja sempre o mesmo e você pode ter certeza de que o retorno de chamada será adicionado uma vez se a prioridade for a mesma.Nos outros 3 casos, o id depende das instâncias do objeto (uma função anônima é um objeto no PHP); portanto, o retorno de chamada é adicionado apenas uma vez se o objeto for a mesma instância e é importante observar que a mesma instância e a mesma classe são duas coisas diferentes.
Veja este exemplo:
Quantos dólares estamos enviando por carregamento de página?
A resposta é 2, porque o id WordPress gera
$sender1
e$sender2
é diferente.O mesmo acontece neste caso:
Acima, usei a função
sent_to_grandma
dentro de closures e, mesmo que o código seja idêntico, os 2 closures são 2 instâncias diferentes de\Closure
objeto, portanto o WP criará 2 ids diferentes, o que fará com que a ação seja adicionada duas vezes, mesmo se a prioridade for a mesma.fonte
Você não pode adicionar a mesma ação ao mesmo gancho de ação , com a mesma prioridade .
Isso é feito para impedir que vários plug-ins que dependem da ação de plug-ins de terceiros aconteçam mais de uma vez (pense em woocommerce e todos os plug-ins de terceiros, como integrações de pagamento de gateway, etc.). Portanto, sem especificar a prioridade, a vovó permanece pobre:
No entanto, se você adicionar prioridade a essas ações:
A avó agora morre com US $ 4 no bolso (1, 2, 3 e o padrão: 10).
fonte