42

我是 cron 工作的新手,不确定这是否可行。

出于安全目的,我考虑制作一个单页脚本来查找某些 GET 值(用户名、密码和安全代码),以确保只有计算机和知道所有 3 个值的人才能运行该命令。

我制作了脚本,它可以在浏览器中运行它,但是是否可以使用 GET 值运行 cron 作业?

一个例子是我跑步

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

这可能吗?

4

9 回答 9

103

$_GET[]&关联数组仅在您的$_POST[]脚本通过 Web 服务器调用时才被初始化。通过命令行调用时,参数在$argv数组中传递,就像 C 一样。

包含从命令行运行时传递给脚本的所有参数的数组。

你的命令是:

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

然后,您将使用parse_str()设置和访问参数:

<?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
于 2012-07-02T16:57:55.140 回答
11

不是直接回答您的问题,而是我认为更好的解决方案:

如果您不希望除 cron 之外的任何人运行脚本,只需将其放在 web-root 之外。这样就根本无法通过网络服务器进行访问。

如果您确实需要以特殊用户身份运行命令,请不要使用GET但有用户登录并检查登录会话(某个设置的会话变量......)并仅在该页面中包含脚本.

您可公开访问的脚本如下所示:

session_start();

if (isset($_SESSION['user']))
{
  include '/path/to/script/outside/of/web-root';
}
else
{
  die('No access.');
}
于 2012-07-02T16:55:52.290 回答
5
* 3 * * * /path_to_script/cronjob.php?username=test&password=test&code=1234

这行不通

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

这有效

此外,您需要使用 parse_str() 函数并获取值

$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str);
echo $first;  // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz
于 2015-06-15T07:56:17.263 回答
5

我意识到这篇文章已经有好几年了,但这篇文章对我帮助最大,所以让我分享我的发现也可以帮助其他人。

我正在使用 DirectAdmin,并且我的 cron 示例都可以正常工作。我从“将所有 Cron 输出发送到电子邮件”中删除了我的电子邮件地址,因此我没有收到有关我的 cronjobs 的电子邮件通知。

我从每 20 分钟运行一次的 cURL 请求开始:

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

请注意URL周围的'',否则不能添加多个参数!

我使用该页面作为一种受 API 启发的方式来触发更新我从另一个网站收集的一些统计数据,其他人可以从我的网站以 JSON 形式获取这些数据。参数 'update' 触发更新过程,参数 'key' 将在验证后触发其他更新操作,我只想在 cronjob 请求更新时完成。

由于上面的 cronjob 基本上在两个方向上都消耗带宽,所以我想使用基于 PHP 的 cronjob,但是遇到了参数问题......所以我发现这篇文章拯救了我的一天:)

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

如您所见,文件名 (index.php) 现在包含在路径中,然后是参数(没有 ? 和 &'s)。

这样你就可以让 cronjob 工作了,但你只完成了一半,因为参数不会通过$_GET... 传递,当你用检查键对脚本进行编码时,这有点烦人$_GET

那么,它是如何工作的呢?很简单(至少经过一些研究),cronjob 通过名为$argv.

因此,有了这些知识,我搜索了一种将其转换为的$argv方法$_GET

  1. 我可以手动和通过 cronjob 触发更新。
  2. 我不必重写我的整个剧本。

我找到了以下解决方案,我们只想在$argv实际设置时执行,所以我将它包装在if isset检查中:

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

希望这对你也有帮助:)

于 2017-01-03T17:01:40.523 回答
2

这将起作用:

* 3 * * * /path_to_script/cronjob.php username=test password=test code=1234
于 2012-07-02T16:56:00.053 回答
1

您应该查看get_opt()$argv函数。

于 2012-07-02T17:00:55.600 回答
0

getopt()当我需要来自 cron 或控制台命令的参数时,我发现使用该函数很有用。

此函数将返回一个选项/参数对数组,或失败时返回 FALSE。

以下示例直接取自 PHP 文档。

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


shell> php example.php -fvalue -h

上面的示例将输出:

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

有关更多选项和不同参数,请查看完整文档。

资源

于 2017-01-04T07:58:23.053 回答
0

username=test&password=test&code=1234

将变成:

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

于 2017-03-28T08:36:00.040 回答
-1

如果您的脚本在多个地方被调用(不仅在您的 cronjob 中),并且您不想更改原始代码(即继续使用$_GET['foo'], $_GET['bar']or $_POST['foo'], $_POST['bar']),您可以使用wget(假设它存在/安装在您的服务器上)。

例如:

* 3 * * * wget -qO- 'http://yoursite.com/path_to_script/cronjob.php?username=test&password=test&code=1234' > /dev/null 2>&1

where-q是用于安静模式(无输出)的选项,O-表示Output to stdout.

由于响应不是您通常会保留的内容(保存到文件),因此该/dev/null 2>&1位确保您的脚本返回的任何响应(echoprintf等)都不会保存在任何地方。

于 2021-02-04T10:48:41.317 回答