Passing $_GET parameters to cron job

2019-01-18 01:17发布

问题:

I am new at cron jobs and am not sure whether this would would work.

For security purposes I thought about making a one page script that looks for certain GET values (a username, a password, and a security code) to make sure that only the computer and someone that knows all 3 can run the command.

I made the script and it works running it in a browser but is it possible to run the cron job with GET values?

a example would be me running

* 3 * * * /path_to_script/cronjob.php?username=test&password=test&code=1234

Is this possible?

回答1:

The $_GET[] & $_POST[] associative arrays are only initialized when your script is invoked via a web server. When invoked via the command line, parameters are passed in the $argv array, just like C.

Contains an array of all the arguments passed to the script when running from the command line.

Your command would be:

* 3 * * * /path_to_script/cronjob.php username=test password=test code=1234 

You would then use parse_str() to set and access the paramaters:

<?php

var_dump($argv);

/*
array(4) {
  [0]=>
  string(27) "/path_to_script/cronjob.php"
  [1]=>
  string(13) "username=test"
  [2]=>
  string(13) "password=test"
  [3]=>
  string(9) "code=1234"
}
*/

parse_str($argv[3], $params);

echo $params['code']; // 1234


回答2:

Not a direct answer to your question but a better solution I think:

If you want nobody except cron to run the script, just place it outside the web-root. That way there is no access via the web-server at all.

If you do need to run the command as a special user as well, don't use GET but have a user login and check for a logged-in session (a certain set session variable...) and include the script in that page only.

Your publicly accessible script would look something like:

session_start();

if (isset($_SESSION['user']))
{
  include '/path/to/script/outside/of/web-root';
}
else
{
  die('No access.');
}


回答3:

* 3 * * * /path_to_script/cronjob.php?username=test&password=test&code=1234

This will not work

* 3 * * * /path_to_script/cronjob.php username=test password=test code=1234

This works

Also, you need to use parse_str() function and get value

$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str);
echo $first;  // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz


回答4:

You should look into the get_opt() or $argv function.



回答5:

This will work:

* 3 * * * /path_to_script/cronjob.php username=test password=test code=1234


回答6:

I find it usefull to use the getopt() function when I need parameters from a cron or a console command.

This function will return an array of option / argument pairs, or FALSE on failure.

The following examples have been directly taken from the PHP documentation.

$options = getopt("f:hp:");
var_dump($options);


shell> php example.php -fvalue -h

The above example will output:

array(2) {
    ["f"]=>
    string(5) "value"
    ["h"]=>
    bool(false)
}

For more options and different parameters take a look at the full documentation.

Resources

  • getopt() - PHP documentation


回答7:

I realize that this post is already several years old but this one helped me the most so let me share my findings as well to help others too.

I'm using DirectAdmin and my cron examples are working both. I removed my email address from the 'Send all Cron output to E-Mail' so I don't receive email notifications of my cronjobs.

I started off with a cURL request which runs every 20 minutes:

*/20 * * * * /usr/local/bin/curl --silent 'https://demo.tld/app/stats/?update&key=1234'

Please note the ' ' around the URL, otherwise you can't add multiple parameters!

I use that page as an API inspired way to trigger the update of some statistics I collect from another website and which others can grab in JSON form from mine. The parameter 'update' triggers the update process and the parameter 'key' will, when validated, trigger additional update actions I only want to be done when the cronjob requests the update.

Since above cronjob basically consumes bandwidth in both directions I wanted to go for a PHP based cronjob, but ran into a problem with the parameters... so that is when I found this post which saved my day :)

*/20 * * * * /usr/local/bin/php /home/path/to/public_html/app/stats/index.php update key=1234

As you can see the filename (index.php) is now included in the path and then the parameters follow (without the ? and &'s).

This way you get the cronjob working BUT you're only half way since the parameters won't be passed on via $_GET... which is a bit annoying when you've coded your script with checks for $_GET keys!

So, how does it work then? Simple (at least after some research), the cronjob passes the parameters to the script via a variable named $argv.

So with that knowledge I searched for a method to transform the $argv into $_GET so:

  1. I can trigger the update both manually and via the cronjob.
  2. I didn't had to rewrite my whole script.

I found the following solution which we only want to execute when $argv is actually set, so I wrapped it in the if isset check:

if( isset( $argv ) )
{
    foreach( $argv as $arg ) {
        $e = explode( '=', $arg );
        if( count($e) == 2 )
            $_GET[$e[0]] = $e[1];
        else    
            $_GET[$e[0]] = 0;
    }
}

Hope this helps you too :)



回答8:

username=test&password=test&code=1234

will became:

php -r "$_GET["username"]="test"; $_GET["password"]="test"; $_GET["code"]="1234"; include "wp-cron.php";'



标签: php linux get cron