问题描述
我有几个站点的 WordPress 多站点。我在 wp-config.php
中将 DISABLE_WP_CRON
设置为 true
。
如果我们使用 wget 或 curl 设置 cron 任务,我们有 30 秒的规则来执行 PHP 脚本。发送大量电子邮件通知并执行其他操作 (可能是远程 SMTP 服务器连接速度很慢,或许这是一大堆来自 bbPress 或任何东西的电子邮件通知) 这么小。
也许我们可以使用这样的东西?
php -q wp-cron.php
但是,它只能运行在多站点中的一个站点 (每个站点在不同的 MySQL 表中都有自己的 cron 任务) 。
P. S. On wpmudev.org forum 我发现奇怪的”solution” 也使用 curl 。
另一个 P. S. WP CLI 具有令人敬畏的 wp cron
命令,但它只允许手动运行 cron 任务 (是的,我们可以使用--url
attr) 。例如:
wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
最佳解决方案
我认为最好的方法是使用 WP-CLI,但是您需要编写一个 bash 脚本来执行此操作。这是一个应该为你做的事情:
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
然后,您需要将此脚本添加到 crontab 中,如果您愿意,可以每分钟运行一次
次佳解决方案
在 wp-config.php
中添加常量后
defined('DISABLE_WP_CRON') or define('DISABLE_WP_CRON', true);
WP-CLI
并且假设您的 config.yml
设置正确,您可以在调用 cron run
时忽略--path
标志。
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.
以 run all due cron tasks 为依据:
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;
如果要让它们同时运行 (首先运行 non-site-specific cron):
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;
您可以将任一选项放在可执行文件中
chmod +x run_all_wp_cron_events_due_now.sh
添加一个 crontab 任务
crontab -e
并可能每分钟执行一次
* * * * * run_all_wp_cron_events_due_now.sh > /dev/null
如果要从 cron 运行 custom command,则可能需要指定 wp-cli 的完整路径才能正常工作。
* * * * * cd /home/username/public_html; /usr/local/bin/php /home/username/wp-cli.phar your-custom-cron-commands run >/dev/null 2>&1
PHP
您在这里需要加载 WordPress 的唯一原因是从数据库中收集 URL,而不是使用 pre-defined 列表。我们只打算 ping 这些 URL,我们并不关心响应是什么。
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 );
}
并在 crontab 中添加一个单独的 custom-cron.php
调用
* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。