25

I have a function to be run every 5 minutes. I've referred following from the codex:

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

I want to run this function just every 5 minuets regardless of when to start. How can I this?

Also it says codex says cron will be run when a visitor visits to the site. Is there any way to run the cron just as per minutes and not waiting for a visit?

let's say the following function should be run every 5 minutes then how can I do that using wp_schedule_event() or wp_cron?

function run_evry_five_minutes(){
    // codes go here
}
5
  • You better look into e.g. Linux cron or 3rd party cron services if you need such a short interval and accuracy,
    – birgire
    Commented Nov 10, 2015 at 8:58
  • site havs heavy traffic.. so no need to consider the time interval.. sure it will be triggered for every 2 or 3 minutes.. clients prefer to do it from functions.php Commented Nov 10, 2015 at 9:01
  • its not possible to trigger a php file without something running on the server with a timer. Commented Nov 10, 2015 at 9:16
  • file? we are talking about a function in functions.php Commented Nov 10, 2015 at 9:18
  • Do you think a free monitoring service could be the ping that triggers CRON? newrelic.com/server-monitoring
    – jgraup
    Commented Jan 30, 2016 at 18:49

7 Answers 7

52

You can create new schedule times via cron_schedules:

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

Now you can schedule your function:

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

To only schedule it once, wrap it in a function and check before running it:

$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');
}

Note the $args parameter! Not specifying the $args parameter in wp_next_scheduled, but having $args for wp_schedule_event, will cause an almost infinite number of the same event to be scheduled (instead of just one).

Finally, create the actual function that you would like to run:

function my_schedule_hook(){
    // codes go here
}

I think it is important to mention that wp-cron is checking the schedule and running due scheduled jobs each time a page is loaded.

So, if you have a low traffic website that only has 1 visitor an hour, wp-cron will only run when that visitor browses your site (once an hour). If your have a high traffic site with visitors requesting a page every second, wp-cron will be triggered every second causing extra load on the server.

The solution is to deactivate wp-cron and trigger it via a real cron job in the time interval of you fastest repeating scheduled wp-cron job (5 min in your case).

Lucas Rolff explains the problem and gives the solution in detail.

As an alternative, you could use a free 3rd party service like UptimeRobot to query your site (and trigger wp-cron) every 5 minutes, if you do not want to deactivate wp-cron and trigger it via a real cron job.

2

@johano's answer correctly explains how to set up a custom interval for WP cron job. The second question isn't answered though, which is how to run a cron every minute:

  1. In the file wp-config.php, add the following code:

    define('DISABLE_WP_CRON', true);
    
  2. Add a cron job (crontab -e on unix/linux):

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

The first part (step 1) will disable WordPress internal cron job. The second part (step 2) will manually run WordPress cron job every minute.

With @Johano's answer (how to run a task every 5 minutes) and mine (how to manually run the cron), you should be able to achieve your goal.

2

If your site does get heavy traffic then you could try using set_transient() to run it (very approximately) every 5 minutes, eg:

function run_every_five_minutes() {
    // Could probably do with some logic here to stop it running if just after running.
    // codes go here
}

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

    // It's better use a hook to call a function in the plugin/theme
    //add_action( 'init', 'run_every_five_minutes' );
}
7
  • Well, er, yeah?!...
    – bonger
    Commented Nov 10, 2015 at 11:10
  • yeah., it's NOT working.. i've used following code in functions.php when a visit make to the page, an update will be made to a table in my database.. function run_evry_five_minutes() { $homepage = file_get_contents('link to visit'); echo $homepage; }. But the DB table is not updated after 6 minutes even. Commented Nov 10, 2015 at 11:43
  • Don't know why it's not working for you but actually thinking about it just using get_transient()/set_transient() without the cron stuff makes a lot more sense, much simpler, will update answer...
    – bonger
    Commented Nov 10, 2015 at 12:03
  • @bonger is this good alternative for wp_schedule_event() ? Commented May 8, 2016 at 19:16
  • @MarkoKunić Don't know to be honest, haven't tried it... it was only offered as a workaround but if you try it out let us know...! (Johano Fierra's answer looks good wordpress.stackexchange.com/a/216121/57034 )
    – bonger
    Commented May 9, 2016 at 11:55
2

You can trigger it in plugin activation instead of on each plugin call:

//Add a utility function to handle logs more nicely.
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 );
        }
    }
}

/**
 * Do not let plugin be accessed directly
 **/
if ( ! defined( 'ABSPATH' ) ) {
    write_log( "Plugin should not be accessed directly!" );
    exit; // Exit if accessed directly
}

/**
 * -----------------------------------------------------------------------------------------------------------
 * Do not forget to trigger a system call to wp-cron page at least each 30mn.
 * Otherwise we cannot be sure that trigger will be called.
 * -----------------------------------------------------------------------------------------------------------
 * Linux command:
 * crontab -e
 * 30 * * * * wget http://<url>/wp-cron.php
 */

/**
 * Add a custom schedule to wp.
 * @param $schedules array The  existing schedules
 *
 * @return mixed The existing + new schedules.
 */
function woocsp_schedules( $schedules ) {
    write_log("Creating custom schedule.");
    if ( ! isset( $schedules["10s"] ) ) {
        $schedules["10s"] = array(
            'interval' => 10,
            'display'  => __( 'Once every 10 seconds' )
        );
    }

    write_log("Custom schedule created.");
    return $schedules;
}

//Add cron schedules filter with upper defined schedule.
add_filter( 'cron_schedules', 'woocsp_schedules' );

//Custom function to be called on schedule triggered.
function scheduleTriggered() {
    write_log( "Scheduler triggered!" );
}
add_action( 'woocsp_cron_delivery', 'scheduleTriggered' );

// Register an activation hook to perform operation only on plugin activation
register_activation_hook(__FILE__, 'woocsp_activation');
function woocsp_activation() {
    write_log("Plugin activating.");

    //Trigger our method on our custom schedule event.
    if ( ! wp_get_schedule( 'woocsp_cron_delivery' ) ) {
        wp_schedule_event( time(), '10s', 'woocsp_cron_delivery' );
    }

    write_log("Plugin activated.");
}

// Deactivate scheduled events on plugin deactivation.
register_deactivation_hook(__FILE__, 'woocsp_deactivation');
function woocsp_deactivation() {
    write_log("Plugin deactivating.");

    //Remove our scheduled hook.
    wp_clear_scheduled_hook('woocsp_cron_delivery');

    write_log("Plugin deactivated.");
}
1

I'm afraid that other than waiting for someone to visit your site which runs a function, the only other option is to set up a cron job on your server using something like this https://stackoverflow.com/questions/878600/how-to-create-cronjob-using-bash or if you have a cpanel style interface on your server, sometimes there is a gui for setting this up.

1
  • yeah,., I understand that.. I already have some crons created from cPnael.. but now I am trying to run a function from functions.php because when the function is in a plugin or in functions.php we can not ask clients to set up a cron from cpanel on their own.. Commented Nov 10, 2015 at 9:00
1

The Cronjob Scheduler plugin allows you to run frequent tasks reliably and timely without anyone having to visit your site, all you need is at least 1 action and a Unix Crontab schedule.

It's very easy to use, and very flexible. You create your own function, and define an action within it. Then you can choose your action from the plugin menu and fire it whenever you want.

0

I have a possible solution using a schedule function and a recursive WP Ajax function.

  1. Create a schedule event of 60 minutes to run a function
  2. This function will trigger a recursive function using Ajax through file_get_contents()
  3. The ajax function will have a counter on the database with a total number of 60 (for each minute inside the hour).
  4. This ajax function will check your counter to:

If counter equal or higher than 60 it will reset counter and await for the next cron job.

If counter multiple of 5 (so at each 5 minutes) it will execute your desired function

And, besides the conditions, it will sleep for 59 seconds sleep(59); (assuming your function it's a quick one). After the sleep, it will trigger itself using file_get_contents()again.

Important things to note:

  1. Create a way to interrupt the process (i.e. checking a value on the DB)
  2. Create a way to prevent 2 processes at same time
  3. On file_get_contents set the time limit on header to 2 or 3 seconds, otherwise the server may have various processes waiting for nothing
  4. You may want to use the set_time_limit(90); to try prevent server to break your function before the sleep

It's a solution, not a good one, and it may get blocked by the server. Using an external cron you can set a simple function and the server will use resources on it once at each 5 minutes. Using this solution, the server will be using resources on it all the time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.