15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar
22.10.2024

Ações do WordPress Explicadas: O Guia Completo do Desenvolvedor para a API de Hooks

WordPress Actions são um componente central da API de Hooks que permite aos desenvolvedores executar funções personalizadas em pontos precisamente definidos durante o ciclo de vida da requisição WordPress — sem nunca tocar nos ficheiros principais. Quando um hook de ação é disparado, cada função registada nesse hook é executada por ordem de prioridade, permitindo uma personalização modular, sustentável e segura para atualizações.

Se está a construir um plugin, a desenvolver um tema, ou a gerir uma instalação WordPress auto-hospedada num ambiente de VPS Hosting, dominar as Actions é indispensável. São o mecanismo principal pelo qual o próprio WordPress é arquitetado — não apenas uma ferramenta de extensão para terceiros.

Como as Actions do WordPress Funcionam Internamente

O WordPress mantém um registo global chamado $wp_filter, que armazena todos os hooks registados — tanto actions como filters. Quando do_action() é chamado, o WordPress procura a entrada desse hook em $wp_filter, ordena os callbacks registados por prioridade e executa-os sequencialmente.

A distinção crítica que muitos tutoriais ignoram: As Actions são do tipo “disparar e esquecer”. Executam callbacks mas descartam quaisquer valores de retorno. Se precisar de interceptar e modificar dados, esse é o trabalho dos Filters, não das Actions. Confundir os dois é um dos erros arquiteturais mais comuns no desenvolvimento de plugins WordPress.

O fluxo de execução é o seguinte:

  1. O núcleo do WordPress (ou um plugin/tema) chama do_action( 'hook_name', ...$args ).
  2. O WordPress resolve todos os callbacks registados em hook_name a partir de $wp_filter.
  3. Os callbacks são ordenados pelo seu valor $priority (ascendente — números mais baixos disparam primeiro).
  4. Cada callback é invocado com os argumentos fornecidos.
  5. Os valores de retorno são silenciosamente ignorados.
  6. A execução continua no código de origem após do_action() retornar.

Esta arquitetura significa que um callback mal escrito registado num hook inicial como init pode bloquear toda a requisição. Faça sempre o perfil dos callbacks de hooks em ambiente de teste antes de implementar em produção.

Registar Actions com add_action()

A função add_action() regista um callable PHP num hook de ação com nome. A sua assinatura completa é:

add_action( string $hook_name, callable $callback, int $priority = 10, int $accepted_args = 1 ): true

Parâmetros explicados:

    $hook_name — O identificador de string exato do hook de ação (ex., wp_login, save_post).
    $callback — Qualquer callable PHP válido: uma função com nome, uma função anónima, um método estático array( 'MyClass', 'method' ), ou um método de objeto array( $object, 'method' ).
    $priority — Ordem de execução relativa a outros callbacks no mesmo hook. Padrão 10. Callbacks com a mesma prioridade são executados por ordem de registo.
    $accepted_args — Quantos argumentos de do_action() passar ao seu callback. Padrão 1. Deve definir isto corretamente ou o seu callback receberá listas de argumentos truncadas.
    
    Exemplo Básico: Ligar ao wp_login
    function notify_admin_on_login( string $user_login, WP_User $user ): void {
        $admin_email = get_option( 'admin_email' );
        $subject     = 'Login Alert: ' . $user_login;
        $message     = sprintf(
            'User "%s" (ID: %d) logged in at %s.',
            $user_login,
            $user->ID,
            current_time( 'mysql' )
        );
        wp_mail( $admin_email, $subject, $message );
    }
    
    // wp_login passes two arguments: $user_login (string) and $user (WP_User object)
    add_action( 'wp_login', 'notify_admin_on_login', 10, 2 );
    Note que accepted_args está definido como 2. Omitir isto e deixar o padrão 1 significa que o seu callback recebe apenas $user_login e nunca vê o objeto WP_User — um bug silencioso que é notoriamente difícil de rastrear.
    Usar Métodos de Objeto e Closures
    O desenvolvimento moderno de WordPress favorece encapsular a lógica dentro de classes:
    class My_Plugin {
    
        public function __construct() {
            add_action( 'init', array( $this, 'register_post_types' ) );
            add_action( 'save_post', array( $this, 'handle_save' ), 20, 3 );
        }
    
        public function register_post_types(): void {
            register_post_type( 'product', array( /* args */ ) );
        }
    
        public function handle_save( int $post_id, WP_Post $post, bool $update ): void {
            if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
                return;
            }
            // Custom save logic here
        }
    }
    
    new My_Plugin();
    Closures anónimas também funcionam, mas não podem ser removidas com remove_action() posteriormente porque o PHP não consegue comparar referências de funções anónimas de forma fiável. Use métodos com nome quando precisar da capacidade de cancelar o registo.
    Remover Actions com remove_action()
    Pode cancelar o registo de qualquer callback — incluindo os adicionados por outros plugins ou temas — usando remove_action(). A prioridade deve corresponder exatamente ao que foi usado em add_action():
    remove_action( 'wp_head', 'wp_generator' ); // Removes WordPress version meta tag
    Para métodos de objeto, precisa de uma referência à mesma instância do objeto:
    // Inside a plugin that exposes its instance
    global $my_plugin_instance;
    remove_action( 'save_post', array( $my_plugin_instance, 'handle_save' ), 20 );
    Um erro comum: chamar remove_action() antes de o add_action() original ter sido executado. Ligue sempre a sua remoção a uma action que dispara após o plugin alvo ser carregado — tipicamente plugins_loaded ou after_setup_theme.
    Referência dos Hooks de Action Principais do WordPress
    A tabela seguinte cobre os hooks de action operacionalmente mais significativos, o seu contexto de disparo e os seus casos de uso práticos.
    
    
    
    
    Nome do Hook
    Dispara Quando
    Casos de Uso Típicos
    Args Passados
    
    
    
    
    muplugins_loaded
    Plugins obrigatórios carregados
    Bootstrapping inicial, constantes
    0
    
    
    plugins_loaded
    Todos os plugins carregados
    Verificações de compatibilidade entre plugins
    0
    
    
    init
    Após carregamento do WP, antes dos cabeçalhos
    Registar CPTs, taxonomias, regras de reescrita
    0
    
    
    wp_loaded
    Após init, tudo carregado
    Registo REST API, tarefas de inicialização tardias
    0
    
    
    wp_enqueue_scripts
    Carregamento de recursos front-end
    Enqueue de CSS/JS para temas e plugins
    0
    
    
    wp_head
    Dentro da tag <head>
    Meta tags, estilos inline, snippets de analytics
    0
    
    
    wp_footer
    Antes de </body>
    Scripts diferidos, pixels de rastreamento
    0
    
    
    admin_init
    Carregamento de páginas de administração
    Registo da Settings API, verificações de capacidade
    0
    
    
    admin_enqueue_scripts
    Carregamento de recursos de administração
    Enqueue de CSS/JS exclusivos do admin
    1 ($hook_suffix)
    
    
    save_post
    Post guardado ou atualizado
    Atualizações de meta, sincronização com API externa, notificações
    3
    
    
    wp_login
    Utilizador autentica
    Registo de auditoria, gestão de sessões
    2
    
    
    user_register
    Novo utilizador criado
    Emails de boas-vindas, sincronização com CRM, atribuição de funções
    1 ($user_id)
    
    
    wp_logout
    Utilizador termina sessão
    Limpeza de sessão, eventos de analytics
    1 ($user_id)
    
    
    switch_theme
    Tema ativo alterado
    Limpeza de cache, migração de opções
    2
    
    
    wp_trash_post
    Post movido para o lixo
    Limpeza de dados relacionados, sincronização externa
    1 ($post_id)
    
    
    rest_api_init
    REST API inicializa
    Registar rotas REST personalizadas
    0
    
    
    template_redirect
    Antes do carregamento do template
    Redirecionamentos, controlo de acesso
    0
    
    
    
    
    do_action() vs do_action_ref_array(): Quando Cada Um se Aplica
    Ambas as funções disparam um hook de ação, mas diferem na forma como os argumentos são passados.
    do_action()
    A função padrão. Os argumentos são passados por valor — os callbacks recebem cópias.
    do_action( 'my_plugin_after_import', $import_id, $result_count, $errors );
    do_action_ref_array()
    Os argumentos são passados como um array, e os objetos dentro desse array são passados por referência (os objetos PHP são sempre semelhantes a referências por padrão desde o PHP 5). Isto é principalmente útil para compatibilidade com código legado ou quando precisa explicitamente que os callbacks modifiquem uma estrutura de dados partilhada.
    $context = array(
        'post_id' => 42,
        'meta'    => array(),
    );
    
    do_action_ref_array( 'my_plugin_process_context', array( &$context ) );
    
    // $context['meta'] may now be populated by hooked callbacks
    Orientação prática: No PHP moderno (7.4+), a diferença comportamental entre os dois é mínima para objetos. Use do_action() por padrão. Recorra a do_action_ref_array() apenas quando integrar com código legado que o espera explicitamente, ou quando precisar que os callbacks modifiquem um valor primitivo (como um inteiro) passado por referência.
    Criar e Documentar Hooks de Action Personalizados
    Ao construir um plugin ou tema destinado a ser estendido por outros, deve definir os seus próprios hooks de ação. É assim que expõe uma superfície de API sem dar a terceiros acesso direto aos seus internos.
    /**
     * Fires after a custom import process completes.
     *
     * @since 1.0.0
     *
     * @param int   $import_id    The ID of the completed import batch.
     * @param int   $record_count Total number of records processed.
     * @param array $errors       Array of WP_Error objects, empty on full success.
     */
    do_action( 'my_plugin_import_complete', $import_id, $record_count, $errors );
    Documente sempre os seus hooks com um DocBlock diretamente acima de do_action(). É isto que alimenta o gerador de documentação para desenvolvedores WordPress e torna o seu plugin de nível profissional. Os desenvolvedores terceiros podem então ligar-se de forma limpa:
    add_action( 'my_plugin_import_complete', function( int $import_id, int $count, array $errors ) {
        if ( ! empty( $errors ) ) {
            // Log errors to an external monitoring service
            error_log( "Import {$import_id} completed with " . count( $errors ) . ' errors.' );
        }
    }, 10, 3 );
    Actions vs Filters: Uma Comparação Definitiva
    Esta é a distinção conceptual mais importante em toda a API de Hooks do WordPress.
    
    
    
    
    Dimensão
    Actions
    Filters
    
    
    
    
    Propósito principal
    Executar efeitos secundários num ponto no tempo
    Interceptar e modificar dados
    
    
    Valor de retorno
    Totalmente ignorado
    Deve retornar o valor (modificado)
    
    
    Função principal
    do_action()
    apply_filters()
    
    
    Registo
    add_action()
    add_filter()
    
    
    Uso típico
    Enviar email, escrever na BD, enqueue de recursos
    Modificar conteúdo de posts, alterar argumentos de query
    
    
    Pode curto-circuitar?
    Não (todos os callbacks são sempre executados)
    Não (mas pode retornar antecipadamente dentro do callback)
    
    
    Mutação de dados
    Não é o padrão pretendido
    Propósito principal
    
    
    
    
    Regra arquitetural chave: Se está a usar add_filter() mas não está a retornar um valor do seu callback, introduziu um bug — o valor filtrado tornar-se-á null ou false dependendo do contexto. Inversamente, se está a usar add_action() e a depender de um valor de retorno, está a usar incorretamente a API.
    Conflitos de Prioridade e Ordem de Execução
    A gestão de prioridades torna-se crítica em ecossistemas de plugins complexos. Considere um cenário onde o WooCommerce, um plugin de cache e o seu código personalizado se ligam todos ao save_post:
    // WooCommerce hooks at priority 10 (default)
    // Your inventory sync needs WooCommerce data to already be saved
    add_action( 'save_post_product', 'sync_inventory_to_erp', 99 );
    
    // A cache purge should happen last, after all data is written
    add_action( 'save_post', 'purge_varnish_cache', 9999 );
    Casos extremos a conhecer:
    
    Prioridades negativas são válidas no WordPress. add_action( 'init', 'my_func', -1 ) dispara antes de qualquer coisa na prioridade 0 ou 10.
    Mesma prioridade, múltiplos callbacks — executam na ordem em que add_action() foi chamado. A ordem de carregamento dos plugins (determinada pelo nome do ficheiro alfabeticamente, ou plugins Plugin Order) afeta portanto o comportamento.
    Hooks recursivos — chamar do_action() para o mesmo hook dentro de um callback para esse hook é tecnicamente possível mas cria loops infinitos. O WordPress não protege contra isto.
    Registo tardio de hooks — se chamar add_action( 'init', ... ) após init já ter disparado, o seu callback nunca será executado nessa requisição. Esta é uma fonte frequente de bugs em código que é executado condicionalmente.
    
    Padrões de Produção do Mundo Real
    Padrão 1: Sistema de Eventos Desacoplado
    Use actions personalizadas para desacoplar componentes de plugins, evitando chamadas de função diretas entre módulos:
    // In your order processing module
    do_action( 'my_shop_order_paid', $order_id, $payment_method, $amount );
    
    // In your email module (separate file, no direct dependency)
    add_action( 'my_shop_order_paid', 'send_payment_confirmation_email', 10, 3 );
    
    // In your analytics module (separate file, no direct dependency)
    add_action( 'my_shop_order_paid', 'track_conversion_event', 20, 3 );
    Este padrão significa que pode desativar o módulo de analytics inteiramente sem tocar no código de processamento de encomendas.
    Padrão 2: Registo Condicional de Hooks
    Evite registar hooks incondicionalmente ao nível superior. Limite-os ao contexto onde são necessários:
    add_action( 'admin_init', function() {
        // Only register these hooks in the admin context
        add_action( 'admin_enqueue_scripts', 'my_plugin_admin_assets' );
        add_action( 'save_post', 'my_plugin_validate_custom_fields', 10, 2 );
    } );
    Padrão 3: Actions de Uma Vez com remove_action() Dentro do Callback
    function my_plugin_run_once(): void {
        // Do something that must only happen once per request
        update_option( 'my_plugin_initialized', true );
    
        // Deregister itself to prevent re-execution if the hook fires again
        remove_action( 'wp_loaded', 'my_plugin_run_once' );
    }
    
    add_action( 'wp_loaded', 'my_plugin_run_once' );
    Considerações de Desempenho em Ambientes Geridos
    Em instalações WordPress de alto tráfego — quer a correr num plano de VPS Hosting ou num Servidor Dedicado — o custo cumulativo de hooks mal otimizados é mensurável.
    Ferramentas de perfil a usar:
    
    Plugin Query Monitor: Mostra cada hook que disparou, cada callback que foi executado e o tempo de execução por callback.
    Xdebug + KCacheGrind: Para perfil aprofundado dos caminhos de execução de callbacks.
    New Relic APM: Para monitorização de desempenho de hooks ao nível de produção.
    
    Princípios de otimização:
    
    Mova operações dispendiosas (queries de base de dados, pedidos HTTP, I/O de ficheiros) para fora de hooks que disparam em cada carregamento de página (init, wp_head) e para hooks que disparam apenas quando necessário (save_post, user_register).
    Use transients ou cache de objetos para memoizar resultados de computações dispendiosas dentro de callbacks de hooks.
    Evite registar centenas de chamadas add_action() incondicionalmente no momento de carregamento do plugin. Registe hooks de forma lazy apenas quando a página de administração ou contexto relevante estiver ativo.
    Em servidores com OPcache ativado (que todos os ambientes PHP corretamente configurados devem ter), a sobrecarga do próprio registo de hooks é negligenciável — o custo está no que os callbacks *fazem*, não no registo.
    
    Se gere a sua própria stack WordPress, garantir que o seu servidor corre PHP 8.1+ com OPcache, um cache de bytecode e um cache de objetos como Redis ou Memcached terá um impacto de desempenho muito maior do que micro-otimizar prioridades de hooks.
    Actions do WordPress no Contexto do Desenvolvimento de Plugins e Temas
    Ao desenvolver um plugin destinado ao repositório WordPress.org ou distribuição comercial, o seu uso da API de Hooks determina diretamente a qualidade do código e as classificações de compatibilidade.
    Melhores práticas para uso de hooks de nível de produção:
    
    Verifique sempre DOING_AUTOSAVE dentro de callbacks save_post para evitar executar lógica dispendiosa em gravações automáticas.
    Verifique nonces e capacidades dentro de qualquer callback de hook que processe dados submetidos pelo utilizador. Nunca confie que o próprio hook fornece segurança.
    Use current_action() para determinar qual hook específico disparou o seu callback quando a mesma função está registada em múltiplos hooks.
    Coloque namespace nos nomes dos seus hooks personalizados para evitar colisões: my_plugin_event_name, não event_name.
    Versione os seus hooks na documentação para que os desenvolvedores saibam quando um hook foi introduzido e quando pode ser descontinuado.
    
    Para equipas que implementam WordPress em infraestrutura com Painéis de Controlo VPS, manter ambientes de teste que espelhem a produção é essencial para testar com segurança as interações de hooks antes da implementação.
    Proteger a Sua Instalação WordPress Juntamente com Actions Personalizadas
    Hooks de ação personalizados que processam dados externos, gerem eventos de autenticação ou interagem com o sistema de ficheiros introduzem superfície de segurança. Combine o desenvolvimento dos seus hooks com um ambiente de hospedagem devidamente protegido.
    Certifique-se de que a sua instalação WordPress usa HTTPS — um Certificado SSL é obrigatório para qualquer site que gerencie autenticação de utilizadores ou submissões de formulários. Callbacks de hooks que disparam em wp_login ou user_register estão a processar dados sensíveis pela rede; sem TLS, esses dados ficam expostos independentemente de quão bem o seu código PHP está escrito.
    Adicionalmente, se o seu plugin usa wp_mail() dentro de callbacks de ação (um padrão comum para notificações), a configuração e reputação de correio do seu servidor afetam diretamente a entregabilidade. Considere uma solução dedicada de Email Hosting com registos SPF, DKIM e DMARC adequados em vez de depender do sendmail ao nível do servidor.
    Matriz de Decisão Técnica e Principais Conclusões
    Use esta lista de verificação ao implementar Actions do WordPress em qualquer projeto:
    Registo de hooks:
    
    Defina $accepted_args explicitamente sempre que o hook passa mais de um argumento
    Use valores de prioridade deliberadamente — documente por que são escolhidas prioridades não padrão
    Registe hooks dentro de construtores de classe ou métodos register_hooks() dedicados, nunca no âmbito global de um ficheiro de plugin
    Limite o registo de hooks ao contexto onde é necessário (admin, front-end, REST API)
    
    Implementação de callbacks:
    
    Verifique sempre DOING_AUTOSAVE, DOING_CRON e wp_is_json_request() onde relevante
    Verifique nonces com check_admin_referer() ou check_ajax_referer() antes de processar qualquer entrada do utilizador
    Nunca dependa de valores de retorno de do_action() — use filters se precisar de dados de volta
    Use current_action() quando um callback serve múltiplos hooks
    
    Design de hooks personalizados:
    
    Coloque namespace em todos os nomes de hooks personalizados com o prefixo do seu plugin/tema
    Documente cada hook personalizado com um DocBlock completo acima de do_action()
  • Passe argumentos suficientes para tornar o hook útil sem expor desnecessariamente o estado interno
  • Prefira do_action() em vez de do_action_ref_array() a menos que tenha uma razão específica

Desempenho e manutenção:

  • Faça o perfil dos callbacks de hooks com Query Monitor antes de implementar em produção
  • Evite queries de base de dados dentro de hooks que disparam em cada requisição
  • Use remove_action() para limpar hooks de terceiros que conflituam com a sua implementação
  • Teste as interações de hooks num ambiente de teste que espelhe a infraestrutura de produção

FAQ

Qual é a diferença entre add_action() e add_filter() no WordPress?

add_action() regista um callback para executar efeitos secundários num ponto específico da execução — o valor de retorno é descartado. add_filter() regista um callback para receber, modificar e retornar um valor. Usar um onde o outro é apropriado é um bug funcional: um callback de filter que não retorna um valor irá anular os dados filtrados.

Por que o meu callback add_action() não está a disparar?

As causas mais comuns são: (1) o nome do hook está mal escrito, (2) add_action() é chamado após o hook já ter disparado na requisição atual, (3) $accepted_args é demasiado baixo e o callback recebe dados errados causando um erro PHP silencioso, ou (4) uma verificação condicional dentro do callback está a impedir a execução. Use Query Monitor para verificar se o hook disparou e se o seu callback foi registado.

Posso usar add_action() dentro de outro callback de ação?

Sim, e este é um padrão comum. Por exemplo, registar hooks dentro de plugins_loaded ou init para garantir que as dependências estão disponíveis. No entanto, o hook interno deve disparar após o externo para que o registo tenha efeito.

O que controla realmente o parâmetro $priority?

Controla a ordem em que múltiplos callbacks registados no mesmo hook são executados. Números mais baixos disparam primeiro. O padrão é 10. Os valores válidos incluem inteiros negativos. Quando dois callbacks partilham a mesma prioridade, executam na ordem em que foram registados via add_action().

Como removo com segurança uma ação adicionada por um plugin de terceiros?

Ligue a sua chamada remove_action() a uma ação que dispara após o plugin ter sido carregado — tipicamente plugins_loaded com alta prioridade, ou after_setup_theme. Deve corresponder exatamente ao nome do hook, referência do callback e prioridade usados na chamada add_action() original. Para métodos de objeto, precisa de acesso à mesma instância do objeto, que plugins respeitáveis expõem através de uma variável global ou de um método estático get_instance().

15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar