admin管理员组

文章数量:1122832

I have WordPress Multisite with several sites. I set up DISABLE_WP_CRON to true in my wp-config.php.

If we set up cron task with wget or curl we have 30 sec rule to execute PHP script. It's so small to send tons of email notifications and do other stuff (maybe remote SMTP server connection is slow, maybe it's really huge bunch of email notifications from bbPress or anything).

Maybe we can use something like this?

php -q wp-cron.php

But it's only run cron to one site in Multisite (each site have their own cron tasks in different MySQL tables).

P. S. On wpmudev forum I found strange "solution" which also use Curl.

Another P. S. WP CLI have awesome wp cron commands but it's only allow run cron tasks manually (yep, we can use --url attr). For example:

wp cron event list --url=multisite
wp cron event list --url=subdomain.multisite

I have WordPress Multisite with several sites. I set up DISABLE_WP_CRON to true in my wp-config.php.

If we set up cron task with wget or curl we have 30 sec rule to execute PHP script. It's so small to send tons of email notifications and do other stuff (maybe remote SMTP server connection is slow, maybe it's really huge bunch of email notifications from bbPress or anything).

Maybe we can use something like this?

php -q wp-cron.php

But it's only run cron to one site in Multisite (each site have their own cron tasks in different MySQL tables).

P. S. On wpmudev.org forum I found strange "solution" which also use Curl.

Another P. S. WP CLI have awesome wp cron commands but it's only allow run cron tasks manually (yep, we can use --url attr). For example:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
Share Improve this question edited Apr 12, 2024 at 5:11 Jesse Nickles 7357 silver badges19 bronze badges asked Nov 3, 2014 at 0:35 Kolya KorobochkinKolya Korobochkin 5791 gold badge4 silver badges11 bronze badges 7
  • Have you taken a look at WP-CLI core code? – kaiser Commented Nov 3, 2014 at 1:36
  • Yes. I dig into the source code right now and trying to understand :) Command to run all tasks (events) not exists, maybe I can create it in future. – Kolya Korobochkin Commented Nov 4, 2014 at 13:27
  • Do you have wp/WP-CLI in your PATH? If yes, why not trigger that from a bash file running in cron? – kaiser Commented Nov 4, 2014 at 13:38
  • Sounds great! But how to run all cron tasks from wp cli? I don't see any commands for this. – Kolya Korobochkin Commented Nov 15, 2014 at 14:45
  • 1 Worth mentioning that if you only have a few sites in your multisite network with no plans to grow you could always just run them individually with wp cron event run --due-now --url=mysite1.com && wp cron event run --due-now --url=mysite2.com etc. ... but if you might be adding sites frequently I think the answer from @Anastis works best. – squarecandy Commented Apr 17, 2021 at 3:49
 |  Show 2 more comments

6 Answers 6

Reset to default 19

After you've added the constant in wp-config.php

defined('DISABLE_WP_CRON') or define('DISABLE_WP_CRON', true);

WP-CLI

And assuming you have your config.yml setup correctly, you can ommit the --path flag when calling cron run.


wp cron event run --due-now

[<hook>…] One or more hooks to run.

[--due-now] Run all hooks due right now.

[--all] Run all hooks.


To run all due cron tasks in order:

function run_crons_due_now_in_order { for SITE_URL in $(wp site list --fields=url --format=csv | tail -n +2 | sort); do wp cron event run --due-now --url="$SITE_URL" && echo -e "\t+ Finished crons for $SITE_URL"; done; echo "Done"; }; run_crons_due_now_in_order;

If you want them to run concurrently (running the non-site-specific cron first):

function run_all_crons_due_now { for SITE_URL in $(wp site list --fields=url --format=csv | tail -n +2 | sort); do wp cron event run --due-now --url="$SITE_URL" && echo -e "\t+ Finished crons for $SITE_URL" & done; wait $(jobs -p); echo "Done"; }; run_all_crons_due_now;

You would want to put either option in an executable file

chmod +x run_all_wp_cron_events_due_now.sh

add a crontab task

crontab -e

and probably execute each minute

* * * * * run_all_wp_cron_events_due_now.sh > /dev/null

If you want to run a custom command from cron, you might need to specify the full paths for wp-cli to work.

* * * * * cd /home/username/public_html; /usr/local/bin/php /home/username/wp-cli.phar your-custom-cron-commands run >/dev/null 2>&1

PHP

The only reason you would need to load up WordPress here is to gather the URLs from the database rather than using a pre-defined list. We're only going to ping those URLs and we don't really care what the response is.

custom-cron.php

<?php

// Load WP
require_once( dirname( __FILE__ ) . '/wp-load.php' );

// Check Version
global $wp_version;
$gt_4_6 = version_compare( $wp_version, '4.6.0', '>=' );

// Get Blogs
$args  = array( 'archived' => 0, 'deleted' => 0, 'public' => 1 );
$blogs = $gt_4_6 ? get_sites( $args ) : @wp_get_sites( $args ); // >= 4.6

// Run Cron on each blog
echo "Running Crons: " . PHP_EOL;
$agent = 'WordPress/' . $wp_version . '; ' . home_url();
$time  = time();

foreach ( $blogs as $blog ) {
    $domain  = $gt_4_6 ? $blog->domain : $blog['domain'];
    $path    = $gt_4_6 ? $blog->path : $blog['path'];
    $command = "http://" . $domain . ( $path ? $path : '/' ) . 'wp-cron.php?doing_wp_cron=' . $time . '&ver=' . $wp_version;

    $ch = curl_init( $command );
    $rc = curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
    $rc = curl_exec( $ch );
    curl_close( $ch );

    print_r( $rc );
    print_r( "\t✔ " . $command . PHP_EOL );
}

And add a single call to your custom-cron.php in a crontab

* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron

I think the best way is to use WP-CLI but you'd need to write a bash script to do this. Here is one that should do it for you:

WP_PATH="/path/to/wp"
for SITE_URL in = $(wp site list --fields=domain,path,archived,deleted --format=csv --path="$WP_PATH" | grep ",0,0$" | awk -F ',' '{print $1 $2}')
do
    for EVENT_HOOK in $(wp cron event list --format=csv --fields=hook,next_run_relative --url="$SITE_URL" --path="$WP_PATH" | grep \"now\"$ | awk -F ',' '{print $1}')
    do
        wp cron event run "$EVENT_HOOK" --url="$SITE_URL" --path="$WP_PATH"
    done
done

You'd then need to add this script to crontab and run it maybe every minute if you like

Easier one-liner with less bash:

wp site list --field=url | xargs -i -n1 wp cron event run --due-now --url="{}"

You can either run it manually or put it in a script and call it from cron as in the other answers.

This is my solution:

global $multisite_hosts;
$multisite_hosts = Array('xxxx.dev.xxx.oondeo.es','x2.dev.xxx.oondeo.es','x3.dev.xxx.oondeo.es');

function run_cron(){
  global $multisite_hosts;
  $host=array_pop($multisite_hosts);
  if (!$host)
    return;
  register_shutdown_function('shutdown');
  if (!isset($_SERVER['HTTP_HOST'])) {
       $_SERVER['HTTP_HOST'] = $host;  // replace with primary host
  }

  require './wp-cron.php';
}

function shutdown()
{
  run_cron();
}
run_cron();

We call this from crontab, hope it helps

Well you can find a full guide here on how to setup the cron job correctly for a WordPress Multisite system to it fires on all sub-sites to and runs the cron jobs. https://support.shorturl.gg/business-marketing-and-seo-forums/topic/you-are-using-wp-cron-incorrectly-in-wordpress-multisite/

Using the standard cron job for WordPress standalone websites doesn't work well as the standard WP cron job only will fire the cron job for the main site and as such no cron jobs will run on sub-sites.

I think you need to tell us what you mean by "run wp-cron.php the right way" first and foremost. According to Wordpress, it doesn't make sense that you disable wp-cron and yet want it to run... From the Linux perspective, wget-ing or /bin/php-ing wp-cron.php would be correct, but it seems your particular host is limiting your number of php invocations for security reasons? -- that part isn't completely clear from your description.

Another question: how many emails are "a ton"? There are great reasons why you shouldn't try to send too many emails that quickly.

You may have to re-think your objectives.

(I would comment instead of replying but I don't have enough reputation on wpstack.)

本文标签: phpRunning WPCron on Multisite networks the right way