所以基本上我有一个Cron .php文件,我用它作为一个引导文件,而不是设置一吨不同的Cron工作,我希望能够做一个包含在我所有的单独的Cron文件在同一时间,而不是等待第一个完成,然后第二个等…
这是我当前的cron.php文件:
/*
* run this file every minute to execute all crons
*/
$included_cron = true;
ini_set('max_execution_time', 0);
require "files/core.php";
/*===== 1st Cron! =====*/
include ROOT.'/files/crons/file1.php';
/*===== 2nd Cron! =====*/
include ROOT.'/files/crons/file2.php';
/*===== 3rd Cron! =====*/
include ROOT.'/files/crons/file3.php';
我怎么能做到这一点,所以我可以有file3.php
包含在file1.php
的同时,这是可能的在PHP?
这个问题的答案是:
<?php
class CronJob extends Threaded {
public function __construct($file) {
$this->file = $file;
}
public function run() {
require_once("files/cron/{$this->file}");
}
protected $file;
}
$workers = 4;
$pool = new Pool($workers);
foreach (["file1.php", "file2.php", "file3.php"] as $file) {
$pool->submit(
new CronJob($file));
}
$pool->shutdown();
?>
这确实感觉很糟糕,但它可能会更好,只是把每个cron作业写为一个线程对象,其中::run包含每个cron任务的业务逻辑。
<?php
class FirstJob extends Threaded {
public function __construct(Threaded $config) {
$this->config = $config;
}
public function run() {
/* do stuff for this cron job */
}
protected $config;
}
class SecondJob extends Threaded {
public function __construct(Threaded $config) {
$this->config = $config;
}
public function run() {
/* do stuff for this cron job */
}
protected $config;
}
class ThirdJob extends Threaded {
public function __construct(Threaded $config) {
$this->config = $config;
}
public function run() {
/* do stuff for this cron job */
}
protected $config;
}
$workers = 4;
$config = new Threaded();
$config["database"] = [
"username" => "mine",
"password" => "secret",
"hostname" => "localhost",
"database" => "data"
];
$pool = new Pool($workers);
/* probably come up with something better, get classes from a database or configuration source or whatever */
$pool->submit(new FirstJob($config));
$pool->submit(new SecondJob($config));
$pool->submit(new ThirdJob($config));
$pool->shutdown();
?>
如果你需要一个单一的入口点来处理所有的任务,但你想要多任务处理,你就必须使用一种支持它的语言。PHP不。
最明显的选择是bash:#!/bin/sh
php /path/to/cron.php file1 &
php /path/to/cron.php file2 &
php /path/to/cron.php file3 &
php /path/to/cron.php file4 &
现在你只需要调整cron.php
接受命令行参数:
if (isset($argv[1]) ) {
$task = $argv[1];
}else{
echo "Must specify task'n";
exit(1);
}
switch($task){
case 'file1':
case 'file2':
case 'file3':
case 'file4':
break;
default:
echo "Invalid task: $task'n";
exit(2);
}
include ROOT . "/files/crons/$task.php";
你想要的就是所谓的多线程。php默认不支持它(没有扩展)。您可以做的是,创建http请求到您的其他脚本。
cron
function http_head($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
curl_close($ch);
}
http_head("file1_url");
http_head("file2_url");
如果你的cron做一些敏感的事情(你不希望谷歌爬虫,或随机用户触发你的cron),你应该实现某种检查,它是否被你的cron调用(例如通过IP地址)。
在file*.php中,你应该告诉php在调用者关闭连接后不要中止。ignore_user_abort(真正);