Come eseguire una funzione ogni 5 minuti?

10 nov 2015, 10:47:43
Visualizzazioni: 81.1K
Voti: 25

Ho una funzione che deve essere eseguita ogni 5 minuti. Ho consultato quanto segue dal codex:

<?php wp_schedule_event(time(), 'hourly', 'my_schedule_hook', $args); ?>

Voglio eseguire questa funzione ogni 5 minuti indipendentemente da quando inizia. Come posso farlo?

Inoltre il codex dice che il cron verrà eseguito quando un visitatore visita il sito. C'è un modo per eseguire il cron in base ai minuti senza dover attendere una visita?

Diciamo che la seguente funzione dovrebbe essere eseguita ogni 5 minuti, come posso farlo usando wp_schedule_event() o wp_cron?

function run_evry_five_minutes(){
    // il codice va qui
}
5
Commenti

Dovresti considerare ad esempio Linux cron o servizi cron di terze parti se hai bisogno di un intervallo così breve e di precisione,

birgire birgire
10 nov 2015 10:58:45

il sito ha molto traffico.. quindi non c'è bisogno di considerare l'intervallo di tempo.. sicuramente verrà attivato ogni 2 o 3 minuti.. i clienti preferiscono farlo dal functions.php

foolishcoder7721 foolishcoder7721
10 nov 2015 11:01:48

non è possibile attivare un file php senza qualcosa che funzioni sul server con un timer.

Andrew Welch Andrew Welch
10 nov 2015 11:16:50

file? stiamo parlando di una funzione in functions.php

foolishcoder7721 foolishcoder7721
10 nov 2015 11:18:27

Pensi che un servizio di monitoraggio gratuito potrebbe essere il ping che attiva CRON? http://newrelic.com/server-monitoring

jgraup jgraup
30 gen 2016 20:49:15
Tutte le risposte alla domanda 7
0
52

Puoi creare nuovi intervalli di pianificazione tramite cron_schedules:

function my_cron_schedules($schedules){
    if(!isset($schedules["5min"])){
        $schedules["5min"] = array(
            'interval' => 5*60,
            'display' => __('Ogni 5 minuti'));
    }
    if(!isset($schedules["30min"])){
        $schedules["30min"] = array(
            'interval' => 30*60,
            'display' => __('Ogni 30 minuti'));
    }
    return $schedules;
}
add_filter('cron_schedules','my_cron_schedules');

Ora puoi pianificare la tua funzione:

wp_schedule_event(time(), '5min', 'my_schedule_hook', $args);

Per pianificarla solo una volta, incapsulala in una funzione e verifica prima di eseguirla:

$args = array(false);
function schedule_my_cron(){
    wp_schedule_event(time(), '5min', 'my_schedule_hook', $args);
}
if(!wp_next_scheduled('my_schedule_hook',$args)){
    add_action('init', 'schedule_my_cron');
}

Nota il parametro $args! Non specificare il parametro $args in wp_next_scheduled, ma averlo per wp_schedule_event, causerà la pianificazione di un numero quasi infinito dello stesso evento (invece di uno solo).

Infine, crea la funzione effettiva che desideri eseguire:

function my_schedule_hook(){
    // il codice va qui
}

Penso sia importante menzionare che wp-cron verifica la pianificazione ed esegue i lavori pianificati ogni volta che viene caricata una pagina.

Quindi, se hai un sito web con poco traffico che ha solo 1 visitatore all'ora, wp-cron verrà eseguito solo quando quel visitatore naviga sul tuo sito (una volta all'ora). Se hai un sito ad alto traffico con visitatori che richiedono una pagina ogni secondo, wp-cron verrà attivato ogni secondo causando un carico extra sul server.

La soluzione è disattivare wp-cron e attivarlo tramite un vero cron job nell'intervallo di tempo del tuo lavoro pianificato wp-cron più veloce (5 minuti nel tuo caso).

Lucas Rolff spiega il problema e fornisce la soluzione in dettaglio.

Come alternativa, potresti utilizzare un servizio di terze parti gratuito come UptimeRobot per interrogare il tuo sito (e attivare wp-cron) ogni 5 minuti, se non vuoi disattivare wp-cron e attivarlo tramite un vero cron job.

30 gen 2016 01:23:34
7

Se il tuo sito riceve molto traffico, potresti provare a utilizzare set_transient() per eseguirlo (approssimativamente) ogni 5 minuti, ad esempio:

function run_every_five_minutes() {
    // Potrebbe essere utile aggiungere della logica qui per evitare che venga eseguito subito dopo l'ultima esecuzione.
    // inserisci qui il codice
}

if ( ! get_transient( 'every_5_minutes' ) ) {
    set_transient( 'every_5_minutes', true, 5 * MINUTE_IN_SECONDS );
    run_every_five_minutes();

    // È meglio utilizzare un hook per chiamare una funzione nel plugin/tema
    //add_action( 'init', 'run_every_five_minutes' );
}
10 nov 2015 12:24:05
Commenti

Beh, ehm, sì?!...

bonger bonger
10 nov 2015 13:10:06

sì.. non funziona.. ho usato il seguente codice in functions.php quando un visitatore accede alla pagina, dovrebbe essere effettuato un aggiornamento a una tabella nel mio database.. function run_evry_five_minutes() { $homepage = file_get_contents('link to visit'); echo $homepage; }. Ma la tabella del DB non viene aggiornata neanche dopo 6 minuti.

foolishcoder7721 foolishcoder7721
10 nov 2015 13:43:49

Non so perché non funzioni per te, ma in realtà pensandoci, usare semplicemente get_transient()/set_transient() senza la parte cron ha molto più senso, molto più semplice, aggiornerò la risposta...

bonger bonger
10 nov 2015 14:03:40

@bonger questa è una buona alternativa a wp_schedule_event() ?

Marko Kunic Marko Kunic
8 mag 2016 22:16:10

@MarkoKunić Onestamente non lo so, non l'ho provato... è stato suggerito solo come soluzione alternativa ma se lo provi facci sapere...! (La risposta di Johano Fierra sembra buona http://wordpress.stackexchange.com/a/216121/57034 )

bonger bonger
9 mag 2016 14:55:31

@bonger funziona, ma è la stessa cosa, se non sei sul sito web, non verrà eseguito

Marko Kunic Marko Kunic
10 mag 2016 10:00:14

Beh sì, come menzionato in vari punti di questa pagina, hai bisogno di un vero cron job in una forma o nell'altra per farlo senza richiedere visitatori...(grazie comunque per il feedback.)

bonger bonger
11 mag 2016 09:20:25
Mostra i restanti 2 commenti
0

La risposta di @johano spiega correttamente come impostare un intervallo personalizzato per un cron job di WP. Tuttavia, la seconda domanda non è stata risposta, ovvero come eseguire un cron ogni minuto:

  1. Nel file wp-config.php, aggiungi il seguente codice:

    define('DISABLE_WP_CRON', true);
    
  2. Aggiungi un cron job (crontab -e su unix/linux):

    1 * * * * wget -q -O - http://example.com/wp-cron.php?doing_wp_cron
    

La prima parte (passo 1) disabilita il cron job interno di WordPress. La seconda parte (passo 2) esegue manualmente il cron job di WordPress ogni minuto.

Con la risposta di @Johano (come eseguire un'attività ogni 5 minuti) e la mia (come eseguire manualmente il cron), dovresti essere in grado di raggiungere il tuo obiettivo.

5 set 2017 07:05:52
0

Puoi attivarlo durante l'attivazione del plugin invece che ad ogni chiamata del plugin:

//Aggiungi una funzione di utilità per gestire i log in modo più elegante.
if ( ! function_exists('write_log')) {
    function write_log ( $log )  {
        if ( is_array( $log ) || is_object( $log ) ) {
            error_log( print_r( $log, true ) );
        } else {
            error_log( $log );
        }
    }
}

/**
 * Non permettere l'accesso diretto al plugin
 **/
if ( ! defined( 'ABSPATH' ) ) {
    write_log( "Il plugin non dovrebbe essere accessibile direttamente!" );
    exit; // Esci se accesso diretto
}

/**
 * -----------------------------------------------------------------------------------------------------------
 * Non dimenticare di attivare una chiamata di sistema alla pagina wp-cron almeno ogni 30 minuti.
 * Altrimenti non possiamo essere sicuri che il trigger venga chiamato.
 * -----------------------------------------------------------------------------------------------------------
 * Comando Linux:
 * crontab -e
 * 30 * * * * wget http://<url>/wp-cron.php
 */

/**
 * Aggiungi una schedulazione personalizzata a WordPress.
 * @param $schedules array Le schedulazioni esistenti
 *
 * @return mixed Le schedulazioni esistenti + nuove.
 */
function woocsp_schedules( $schedules ) {
    write_log("Creazione di una schedulazione personalizzata.");
    if ( ! isset( $schedules["10s"] ) ) {
        $schedules["10s"] = array(
            'interval' => 10,
            'display'  => __( 'Ogni 10 secondi' )
        );
    }

    write_log("Schedulazione personalizzata creata.");
    return $schedules;
}

//Aggiungi il filtro per le schedulazioni cron con la schedulazione definita sopra.
add_filter( 'cron_schedules', 'woocsp_schedules' );

//Funzione personalizzata da chiamare quando la schedulazione viene attivata.
function scheduleTriggered() {
    write_log( "Schedulazione attivata!" );
}
add_action( 'woocsp_cron_delivery', 'scheduleTriggered' );

// Registra un hook di attivazione per eseguire operazioni solo durante l'attivazione del plugin
register_activation_hook(__FILE__, 'woocsp_activation');
function woocsp_activation() {
    write_log("Attivazione del plugin in corso.");

    //Attiva il nostro metodo sull'evento della schedulazione personalizzata.
    if ( ! wp_get_schedule( 'woocsp_cron_delivery' ) ) {
        wp_schedule_event( time(), '10s', 'woocsp_cron_delivery' );
    }

    write_log("Plugin attivato.");
}

// Disattiva gli eventi schedulati durante la disattivazione del plugin.
register_deactivation_hook(__FILE__, 'woocsp_deactivation');
function woocsp_deactivation() {
    write_log("Disattivazione del plugin in corso.");

    //Rimuovi il nostro hook schedulato.
    wp_clear_scheduled_hook('woocsp_cron_delivery');

    write_log("Plugin disattivato.");
}

5 mar 2018 13:05:42
1

Purtroppo, a parte aspettare che qualcuno visiti il tuo sito e attivi una funzione, l'unica altra opzione è configurare un cron job sul tuo server usando qualcosa come questo https://stackoverflow.com/questions/878600/how-to-create-cronjob-using-bash oppure, se hai un'interfaccia di tipo cpanel sul tuo server, a volte c'è una GUI per configurarlo.

10 nov 2015 10:55:05
Commenti

sì, capisco... ho già alcuni cron creati da cPnael... ma ora sto cercando di eseguire una funzione da functions.php perché quando la funzione è in un plugin o in functions.php non possiamo chiedere ai clienti di configurare un cron da cpanel da soli...

foolishcoder7721 foolishcoder7721
10 nov 2015 11:00:08
0

Il plugin Cronjob Scheduler ti permette di eseguire attività frequenti in modo affidabile e puntuale senza che nessuno debba visitare il tuo sito, tutto ciò di cui hai bisogno è almeno 1 azione e una pianificazione Unix Crontab.

È molto semplice da usare e estremamente flessibile. Puoi creare la tua funzione personalizzata e definire un'azione al suo interno. Successivamente potrai selezionare la tua azione dal menu del plugin e attivarla quando vuoi.

30 gen 2016 02:22:55
0

Ho una possibile soluzione utilizzando una funzione schedulata e una funzione ricorsiva WP Ajax.

  1. Crea un evento schedulato ogni 60 minuti per eseguire una funzione
  2. Questa funzione attiverà una funzione ricorsiva usando Ajax tramite file_get_contents()
  3. La funzione ajax avrà un contatore nel database con un numero totale di 60 (per ogni minuto all'interno dell'ora).
  4. Questa funzione ajaz controllerà il tuo contatore per:

Se il contatore è uguale o superiore a 60 resetta il contatore e aspetta il prossimo cron job.

Se il contatore è multiplo di 5 (quindi ogni 5 minuti) eseguirà la tua funzione desiderata

E, oltre alle condizioni, dormirà per 59 secondi sleep(59); (assumendo che la tua funzione sia veloce). Dopo il sleep, si attiverà nuovamente usando file_get_contents().

Cose importanti da notare:

  1. Crea un modo per interrompere il processo (es. controllando un valore nel DB)
  2. Crea un modo per prevenire 2 processi contemporaneamente
  3. Su file_get_contents imposta il time limit nell'header a 2 o 3 secondi, altrimenti il server potrebbe avere vari processi in attesa per nulla
  4. Potresti voler usare set_time_limit(90); per cercare di prevenire che il server interrompa la tua funzione prima del sleep

È una soluzione, non una buona, e potrebbe essere bloccata dal server. Usando un cron esterno puoi impostare una semplice funzione e il server userà risorse su di essa una volta ogni 5 minuti. Usando questa soluzione, il server userà risorse su di essa tutto il tempo.

10 nov 2015 14:46:52