Cum să executăm o funcție la fiecare 5 minute?

10 nov. 2015, 10:47:43
Vizualizări: 81.1K
Voturi: 25

Am o funcție care trebuie să ruleze la fiecare 5 minute. Am consultat următoarele din codex:

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

Vreau să rulez această funcție doar la fiecare 5 minute, indiferent de momentul de start. Cum pot face acest lucru?

De asemenea, codexul menționează că cron-ul va rula când un vizitator accesează site-ul. Există vreo modalitate de a rula cron-ul conform intervalului de minute stabilit și fără a aștepta o vizită?

Să zicem că următoarea funcție ar trebui să ruleze la fiecare 5 minute, cum pot face asta folosind wp_schedule_event() sau wp_cron?

function run_evry_five_minutes(){
    // codul vine aici
}
5
Comentarii

Ar fi mai bine să te uiți, de exemplu, la cron-ul Linux sau serviciile cron de la terți dacă ai nevoie de un interval atât de scurt și precizie,

birgire birgire
10 nov. 2015 10:58:45

site-ul are trafic mare.. deci nu este nevoie să iei în considerare intervalul de timp.. sigur va fi declanșat la fiecare 2 sau 3 minute.. clienții preferă să facă asta din functions.php

foolishcoder7721 foolishcoder7721
10 nov. 2015 11:01:48

nu este posibil să declanșezi un fișier php fără ceva care să ruleze pe server cu un cronometru.

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

fișier? vorbim despre o funcție în functions.php

foolishcoder7721 foolishcoder7721
10 nov. 2015 11:18:27

Crezi că un serviciu gratuit de monitorizare ar putea fi ping-ul care declanșează CRON? http://newrelic.com/server-monitoring

jgraup jgraup
30 ian. 2016 20:49:15
Toate răspunsurile la întrebare 7
0
52

Puteți crea noi intervale de programare prin cron_schedules:

function my_cron_schedules($schedules){
    if(!isset($schedules["5min"])){
        $schedules["5min"] = array(
            'interval' => 5*60,
            'display' => __('O dată la 5 minute'));
    }
    if(!isset($schedules["30min"])){
        $schedules["30min"] = array(
            'interval' => 30*60,
            'display' => __('O dată la 30 de minute'));
    }
    return $schedules;
}
add_filter('cron_schedules','my_cron_schedules');

Acum puteți programa funcția dumneavoastră:

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

Pentru a o programa o singură dată, înfășurați-o într-o funcție și verificați înainte de a o rula:

$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ți parametrul $args! Dacă nu specificați parametrul $args în wp_next_scheduled, dar aveți $args pentru wp_schedule_event, acest lucru va provoca programarea unui număr aproape infinit de același eveniment (în loc de doar unul).

În final, creați funcția efectivă pe care doriți să o rulați:

function my_schedule_hook(){
    // codul aici
}

Cred că este important de menționat că wp-cron verifică programarea și rulează sarcinile programate la fiecare încărcare de pagină.

Deci, dacă aveți un site cu trafic redus care are doar 1 vizitator pe oră, wp-cron va rula doar când acel vizitator navighează pe site-ul dumneavoastră (o dată pe oră). Dacă aveți un site cu trafic ridicat, cu vizitatori care solicită o pagină în fiecare secundă, wp-cron va fi declanșat în fiecare secundă, ceea ce va crea o încărcare suplimentară pe server.

Soluția este să dezactivați wp-cron și să-l declanșați printr-un cron job real în intervalul de timp al celei mai rapide sarcini programate wp-cron (5 minute în cazul dumneavoastră).

Lucas Rolff explică problema și oferă soluția în detaliu.

Ca alternativă, puteți utiliza un serviciu gratuit terță parte precum UptimeRobot pentru a interoga site-ul dumneavoastră (și a declanșa wp-cron) la fiecare 5 minute, dacă nu doriți să dezactivați wp-cron și să-l declanșați printr-un cron job real.

30 ian. 2016 01:23:34
7

Dacă site-ul tău primește trafic intens, ai putea încerca să folosești set_transient() pentru a-l rula (aproximativ) la fiecare 5 minute, de exemplu:

function run_every_five_minutes() {
    // Ar fi bine să adăugăm o logică aici pentru a preveni rularea repetată imediat.
    // codul va fi aici
}

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

    // Este mai bine să folosești un hook pentru a apela o funcție din plugin/theme
    //add_action( 'init', 'run_every_five_minutes' );
}
10 nov. 2015 12:24:05
Comentarii

Păi, ăă, da?!...

bonger bonger
10 nov. 2015 13:10:06

da., NU funcționează.. am folosit următorul cod în functions.php când un vizitator accesează pagina, ar trebui să se facă o actualizare într-un tabel din baza mea de date.. function run_evry_five_minutes() { $homepage = file_get_contents('link to visit'); echo $homepage; }. Dar tabelul din baza de date nu se actualizează nici după 6 minute.

foolishcoder7721 foolishcoder7721
10 nov. 2015 13:43:49

Nu știu de ce nu funcționează pentru tine, dar de fapt gândindu-mă la asta, folosirea direct a get_transient()/set_transient() fără cron are mult mai mult sens, mult mai simplu, voi actualiza răspunsul...

bonger bonger
10 nov. 2015 14:03:40

@bonger este aceasta o alternativă bună pentru wp_schedule_event()?

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

@MarkoKunić Sincer să fiu, nu știu, nu am încercat... a fost oferită doar ca o soluție temporară, dar dacă o încerci, spune-ne cum merge...! (Răspunsul lui Johano Fierra pare bun http://wordpress.stackexchange.com/a/216121/57034 )

bonger bonger
9 mai 2016 14:55:31

@bonger funcționează, dar este același lucru, dacă nu ești pe site, nu se va executa

Marko Kunic Marko Kunic
10 mai 2016 10:00:14

Da, așa cum am menționat în diferite locuri pe această pagină, ai nevoie de un cron job real într-o formă sau alta pentru a face asta fără a depinde de vizitatori...(mulțumesc totuși pentru feedback.)

bonger bonger
11 mai 2016 09:20:25
Arată celelalte 2 comentarii
0

Răspunsul lui @johano explică corect cum să configurezi un interval personalizat pentru un job cron în WordPress. Însă a doua întrebare nu a fost răspunsă, și anume cum să rulezi un cron în fiecare minut:

  1. În fișierul wp-config.php, adaugă următorul cod:

    define('DISABLE_WP_CRON', true);
    
  2. Adaugă un job cron (crontab -e pe Unix/Linux):

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

Prima parte (pasul 1) va dezactiva cron job-ul intern al WordPress. A doua parte (pasul 2) va rula manual cron job-ul WordPress în fiecare minut.

Cu răspunsul lui @Johano (cum să rulezi o sarcină la fiecare 5 minute) și al meu (cum să rulezi manual cron-ul), ar trebui să poți atinge obiectivul tău.

5 sept. 2017 07:05:52
0

Puteți declanșa acest lucru în activarea pluginului în loc de la fiecare apel al pluginului:

//Adăugăm o funcție utilitară pentru a gestiona jurnalele mai ușor.
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 );
        }
    }
}

/**
 * Nu permiteți accesul direct la plugin
 **/
if ( ! defined( 'ABSPATH' ) ) {
    write_log( "Pluginul nu ar trebui accesat direct!" );
    exit; // Ieșire dacă este accesat direct
}

/**
 * -----------------------------------------------------------------------------------------------------------
 * Nu uitați să declanșați un apel de sistem către pagina wp-cron cel puțin la fiecare 30 de minute.
 * Altfel, nu putem fi siguri că declanșatorul va fi apelat.
 * -----------------------------------------------------------------------------------------------------------
 * Comanda Linux:
 * crontab -e
 * 30 * * * * wget http://<url>/wp-cron.php
 */

/**
 * Adăugăm un program personalizat în WordPress.
 * @param $schedules array Programele existente
 *
 * @return mixed Programele existente + cele noi.
 */
function woocsp_schedules( $schedules ) {
    write_log("Se creează programul personalizat.");
    if ( ! isset( $schedules["10s"] ) ) {
        $schedules["10s"] = array(
            'interval' => 10,
            'display'  => __( 'O dată la 10 secunde' )
        );
    }

    write_log("Programul personalizat a fost creat.");
    return $schedules;
}

//Adăugăm filtrul pentru programe cron cu programul definit mai sus.
add_filter( 'cron_schedules', 'woocsp_schedules' );

//Funcție personalizată care va fi apelată la declanșarea programării.
function scheduleTriggered() {
    write_log( "Programatorul a fost declanșat!" );
}
add_action( 'woocsp_cron_delivery', 'scheduleTriggered' );

// Înregistrăm un hook de activare pentru a efectua operații doar la activarea pluginului
register_activation_hook(__FILE__, 'woocsp_activation');
function woocsp_activation() {
    write_log("Pluginul se activează.");

    //Declanșăm metoda noastră pe evenimentul nostru personalizat.
    if ( ! wp_get_schedule( 'woocsp_cron_delivery' ) ) {
        wp_schedule_event( time(), '10s', 'woocsp_cron_delivery' );
    }

    write_log("Pluginul a fost activat.");
}

// Dezactivăm evenimentele programate la dezactivarea pluginului.
register_deactivation_hook(__FILE__, 'woocsp_deactivation');
function woocsp_deactivation() {
    write_log("Pluginul se dezactivează.");

    //Eliminăm hook-ul nostru programat.
    wp_clear_scheduled_hook('woocsp_cron_delivery');

    write_log("Pluginul a fost dezactivat.");
}

5 mar. 2018 13:05:42
1

Îmi pare rău, dar în afară de a aștepta ca cineva să viziteze site-ul tău, unde rulează o funcție, singura altă opțiune este să configurezi un job cron pe server folosind ceva de genul https://stackoverflow.com/questions/878600/how-to-create-cronjob-using-bash sau, dacă ai o interfață de tip cpanel pe server, uneori există o interfață grafică pentru configurarea acestuia.

10 nov. 2015 10:55:05
Comentarii

da, înțeleg asta.. deja am câteva cron-uri create din cPnael.. dar acum încerc să rulez o funcție din functions.php pentru că atunci când funcția este într-un plugin sau în functions.php nu putem cere clienților să configureze un cron din cpanel singuri..

foolishcoder7721 foolishcoder7721
10 nov. 2015 11:00:08
0

Pluginul Cronjob Scheduler vă permite să rulați sarcini frecvente în mod fiabil și la timp, fără ca cineva să fie nevoit să viziteze site-ul dvs. Tot ce aveți nevoie este cel puțin 1 acțiune și un program Unix Crontab.

Este foarte ușor de utilizat și extrem de flexibil. Creați propria funcție și definiți o acțiune în interiorul acesteia. Apoi puteți alege acțiunea din meniul plugin-ului și o puteți declanșa oricând doriți.

30 ian. 2016 02:22:55
0

Am o posibilă soluție folosind o funcție programată și o funcție recursivă WP Ajax.

  1. Creează un eveniment programat la fiecare 60 de minute pentru a rula o funcție
  2. Această funcție va declanșa o funcție recursivă folosind Ajax prin file_get_contents()
  3. Funcția Ajax va avea un contor în baza de date cu un număr total de 60 (pentru fiecare minut din oră).
  4. Această funcție Ajax va verifica contorul pentru:

Dacă contorul este egal sau mai mare decât 60, va reseta contorul și va aștepta următoarea acțiune cron.

Dacă contorul este multiplu de 5 (deci la fiecare 5 minute) va executa funcția dorită

Și, pe lângă condiții, va aștepta 59 de secunde sleep(59); (presupunând că funcția ta este rapidă). După așteptare, se va declanșa din nou folosind file_get_contents().

Lucruri importante de notat:

  1. Creează o modalitate de a întrerupe procesul (de ex. verificând o valoare în baza de date)
  2. Creează o modalitate de a preveni rularea a 2 procese simultan
  3. La file_get_contents setează limita de timp în header la 2 sau 3 secunde, altfel serverul poate avea mai multe procese care așteaptă degeaba
  4. Poți dori să folosești set_time_limit(90); pentru a încerca să previi serverul să întrerupă funcția înainte de sleep

Este o soluție, nu una bună, și poate fi blocată de server. Folosind un cron extern poți seta o funcție simplă și serverul va folosi resurse pentru ea o dată la fiecare 5 minute. Folosind această soluție, serverul va folosi resurse pentru ea tot timpul.

10 nov. 2015 14:46:52