How to start/stop a cronjob using PHP?

家住魔仙堡 提交于 2019-11-29 22:39:02

I did some research and found in a forum, the following message:

Call "crontab -e" with the EDITOR environment variable set to a php script. That script can modify the file and when it exits crontab will re-read the file and update.

So, I have tried something, and it worked. I will paste the working code below:

#!/usr/bin/php
<?php

$on  = "* * * * * /usr/bin/php /home/user/every_minute_script.php\n";
$off = "# * * * * * /usr/bin/php /home/user/every_minute_script.php\n";

$param    = isset( $argv[1] ) ? $argv[1] : '';
$filename = isset( $argv[2] ) ? $argv[2] : '';

if ( $param == 'activate' )
{
    shell_exec( 'export EDITOR="/home/user/cron.php on"; crontab -e' );
}
elseif( $param == 'deactivate' )
{
    shell_exec( 'export EDITOR="/home/user/cron.php off"; crontab -e' );
}
elseif( in_array( $param, array( 'on', 'off' ) ) )
{
    if ( !is_writable( $filename ) )
        exit();

    $crontab = file( $filename );
    $key = array_search( $param == 'on' ? $off : $on, $crontab );

    if ( $key === false )
        exit();

    $crontab[$key] = $param == 'on' ? $on : $off;
    sleep( 1 );
    file_put_contents( $filename, implode( '', $crontab ) );
}

exit();

?>

As it is, we have a single script named cron.php located at /home/user folder, set to be executable (chmod a+x cron.php) and called from the command-line (PHP-CLI). Later I will tweak it to run from the web, which is my intent.

Usage: ./cron.php activate to enable the cronjob and ./cron.php deactivate to disable it.

The script sets the EDITOR environment variable properly (to itself) and then calls crontab -e, which on its turn calls the EDITOR (which is now the same cron.php script) passing the temporary crontab file location as an argument. Then, the proper crontab line is found and changed, and the modified version is saved, substituting the temporary file. When the script exits, crontab will update.

This does exactly what I wanted, and fit my needs.

The other answers are nice and may fit different needs and scenarios, and I want to thank everybody who contributed.

Rather than messing programatically with crontab (which is subtle and quick to anger), I'd suggest making a check inside your every_minute_script.php:

if (!file_exists('/your/path/run_every_minute_script')) {
  exit;
}

This way, the script will still start every minute, but if the condition isn't met (/your/path/run_every_minute_script doesn't exist), it will terminate immediately without further processing.

(Of course, you can substitute different conditions there, e.g. checking the database for permission etc.)


If you need the output mailed, you can use a wrapper script. Crontab:

* * * * * /your/path/wrapper.sh > /dev/null 2> /dev/null

The wrapper script then runs the job proper, collects its output and errors, and if those aren't empty, mails them out (note that you could also make the check inside the wrapper script; we didn't, as it relied on database).

Here's a pretty cool tutorial for creating exactly this kind of functionality with PHP.

Put your stop/start condition at the start of every_minute_script.php

if($condition == false) {
    exit();
}

Could you place some kind of logic at the beginning of every_minute_script.php that checks a flag to see if it should do anything? That way it could spin up and then just quickly stop if there is no work to do.

Or is that too inefficient for your purposes?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!